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
This commit is contained in:
Sam 2013-03-20 21:45:01 -07:00
parent 31c27aa487
commit 0089619ed9
5 changed files with 79 additions and 29 deletions

View File

@ -22,9 +22,12 @@ Discourse.Eyeline = function Eyeline(selector) {
@method update @method update
**/ **/
Discourse.Eyeline.prototype.update = function() { 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; _this = this;
// before anything ... let us not do anything if we have no focus
if (!Discourse.get('hasFocus')) { return; }
docViewTop = $(window).scrollTop(); docViewTop = $(window).scrollTop();
windowHeight = $(window).height(); windowHeight = $(window).height();
docViewBottom = docViewTop + windowHeight; docViewBottom = docViewTop + windowHeight;
@ -38,9 +41,10 @@ Discourse.Eyeline.prototype.update = function() {
// Whether we've seen any elements in this search // Whether we've seen any elements in this search
foundElement = false; foundElement = false;
$results = $(this.selector);
return $results.each(function(i, elem) { return $elements.each(function(i, elem) {
var $elem, elemBottom, elemTop, markSeen; var $elem, elemBottom, elemTop, markSeen;
$elem = $(elem); $elem = $(elem);
elemTop = $elem.offset().top; elemTop = $elem.offset().top;
elemBottom = elemTop + $elem.height(); elemBottom = elemTop + $elem.height();
@ -71,7 +75,7 @@ Discourse.Eyeline.prototype.update = function() {
if (i === 0) { if (i === 0) {
_this.trigger('sawTop', { detail: $elem }); _this.trigger('sawTop', { detail: $elem });
} }
if (i === ($results.length - 1)) { if (i === ($elements.length - 1)) {
return _this.trigger('sawBottom', { detail: $elem }); return _this.trigger('sawBottom', { detail: $elem });
} }
}); });

View File

@ -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 // there is a condition where the view never calls unsubscribe, navigate to a topic from a topic
bus.unsubscribe('/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; var posts, topic;
topic = _this.get('content'); topic = _this.get('content');
if (data.notification_level_change) { if (data.notification_level_change) {
@ -289,7 +290,7 @@ Discourse.TopicController = Discourse.ObjectController.extend({
topic.set('highest_post_number', data.post_number); topic.set('highest_post_number', data.post_number);
topic.set('last_poster', data.user); topic.set('last_poster', data.user);
topic.set('last_posted_at', data.created_at); 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); post.set('version', post.get('version') + 1);
} }
return post["delete"](); return post["delete"]();
},
postRendered: function(post) {
var onPostRendered = this.get('onPostRendered');
if (onPostRendered) {
onPostRendered(post);
}
} }
}); });

View File

@ -240,8 +240,10 @@ Discourse.PostView = Discourse.View.extend({
$post = this.$(); $post = this.$();
post = this.get('post'); post = this.get('post');
postNumber = post.get('scrollToAfterInsert');
// Do we want to scroll to this post now that we've inserted it? // 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); Discourse.TopicView.scrollTo(this.get('post.topic_id'), postNumber);
if (postNumber === post.get('post_number')) { if (postNumber === post.get('post_number')) {
$contents = $('.topic-body .contents', $post); $contents = $('.topic-body .contents', $post);
@ -271,7 +273,13 @@ Discourse.PostView = Discourse.View.extend({
} }
// Find all the quotes // 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);
}
} }
}); });

View File

@ -7,10 +7,7 @@
@module Discourse @module Discourse
**/ **/
Discourse.TopicPostsView = Em.CollectionView.extend({ Discourse.TopicPostsView = Em.CollectionView.extend({
itemViewClass: Discourse.PostView, itemViewClass: Discourse.PostView
didInsertElement: function() {
this.get('topicView').postsRendered();
}
}); });

View File

@ -110,22 +110,31 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
// This view is being removed. Shut down operations // This view is being removed. Shut down operations
willDestroyElement: function() { willDestroyElement: function() {
var _ref; var screenTrack, controller;
this.unbindScrolling(); this.unbindScrolling();
this.get('controller').unsubscribe();
if (_ref = this.get('screenTrack')) { controller = this.get('controller');
_ref.stop(); controller.unsubscribe();
controller.set('onPostRendered', null);
screenTrack = this.get('screenTrack');
if (screenTrack) {
screenTrack.stop();
} }
this.set('screenTrack', null); this.set('screenTrack', null);
$(window).unbind('scroll.discourse-on-scroll'); $(window).unbind('scroll.discourse-on-scroll');
$(document).unbind('touchmove.discourse-on-scroll'); $(document).unbind('touchmove.discourse-on-scroll');
$(window).unbind('resize.discourse-on-scroll'); $(window).unbind('resize.discourse-on-scroll');
return this.resetExamineDockCache();
this.resetExamineDockCache();
}, },
didInsertElement: function(e) { didInsertElement: function(e) {
var eyeline, onScroll, screenTrack, var eyeline, onScroll, screenTrack, controller,
_this = this; _this = this;
onScroll = Discourse.debounce((function() { onScroll = Discourse.debounce((function() {
return _this.onScroll(); return _this.onScroll();
}), 10); }), 10);
@ -133,7 +142,12 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
$(document).bind('touchmove.discourse-on-scroll', onScroll); $(document).bind('touchmove.discourse-on-scroll', onScroll);
$(window).bind('resize.discourse-on-scroll', onScroll); $(window).bind('resize.discourse-on-scroll', onScroll);
this.bindScrolling(); this.bindScrolling();
this.get('controller').subscribe(); controller = this.get('controller');
controller.subscribe();
controller.set('onPostRendered', function(){
_this.postsRendered.apply(_this);
});
// Insert our screen tracker // Insert our screen tracker
screenTrack = Discourse.ScreenTrack.create({ topic_id: this.get('topic.id') }); 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 // Track the user's eyeline
eyeline = new Discourse.Eyeline('.topic-post'); 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('saw', function(e) {
eyeline.on('sawTop', function(e) { _this.prevPage(e.detail); }); _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.set('eyeline', eyeline);
this.$().on('mouseup.discourse-redirect', '.cooked a, a.track-link', function(e) { this.$().on('mouseup.discourse-redirect', '.cooked a, a.track-link', function(e) {
return Discourse.ClickTrack.trackClick(e); return Discourse.ClickTrack.trackClick(e);
}); });
return this.onScroll(); this.onScroll();
}, },
// Triggered from the post view all posts are rendered // Triggered whenever any posts are rendered, debounced to save over calling
postsRendered: function(postDiv, post) { postsRendered: Discourse.debounce(function() {
var $lastPost, $window, var $lastPost, $window,
_this = this; _this = this;
$window = $(window); $window = $(window);
@ -166,7 +194,7 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
// last is not in view, so only examine in 2 seconds // last is not in view, so only examine in 2 seconds
Em.run.later(function() { _this.examineRead(); }, 2000); Em.run.later(function() { _this.examineRead(); }, 2000);
} }
}, }, 100),
resetRead: function(e) { resetRead: function(e) {
var _this = this; 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 // Called for every post seen
postSeen: function($post) { postSeen: function($post) {
var post, postView, _ref; var post, postView, _ref;
@ -192,7 +226,8 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
} }
if (!post.get('read')) { if (!post.get('read')) {
post.set('read', true); 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() { postCountChanged: (function() {
this.set('seenBottom', false); this.set('seenBottom', false);
var eyeline = this.get('eyeline');
if (eyeline) eyeline.update()
}).observes('topic.highest_post_number'), }).observes('topic.highest_post_number'),
loadMore: function(post) { loadMore: function(post) {