This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/components/screen_track.js.coffee
2013-02-05 14:16:51 -05:00

129 lines
3.3 KiB
CoffeeScript

# We use this class to track how long posts in a topic are on the screen.
# This could be a potentially awesome metric to keep track of.
window.Discourse.ScreenTrack = Ember.Object.extend
# Don't send events if we haven't scrolled in a long time
PAUSE_UNLESS_SCROLLED: 1000*60*3
# After 6 minutes stop tracking read position on post
MAX_TRACKING_TIME: 1000*60*6
totalTimings: {}
# Elements to track
timings: {}
topicTime: 0
cancelled: false
track: (elementId, postNumber) ->
@timings["##{elementId}"] =
time: 0
postNumber: postNumber
guessedSeen: (postNumber) ->
@highestSeen = postNumber if postNumber > (@highestSeen || 0)
# Reset our timers
reset: ->
@lastTick = new Date().getTime()
@lastFlush = 0
@cancelled = false
# Start tracking
start: ->
@reset()
@lastScrolled = new Date().getTime()
@interval = setInterval =>
@tick()
, 1000
# Cancel and eject any tracking we have buffered
cancel: ->
@cancelled = true
@timings = {}
@topicTime = 0
clearInterval(@interval)
@interval = null
# Stop tracking and flush buffered read records
stop: ->
clearInterval(@interval)
@interval = null
@flush()
scrolled: ->
@lastScrolled = new Date().getTime()
flush: ->
return if @cancelled
# We don't log anything unless we're logged in
return unless Discourse.get('currentUser')
newTimings = {}
Object.values @timings, (timing) =>
@totalTimings[timing.postNumber] ||= 0
if timing.time > 0 and @totalTimings[timing.postNumber] < @MAX_TRACKING_TIME
@totalTimings[timing.postNumber] += timing.time
newTimings[timing.postNumber] = timing.time
timing.time = 0
topicId = @get('topic_id')
highestSeenByTopic = Discourse.get('highestSeenByTopic')
if (highestSeenByTopic[topicId] || 0) < @highestSeen
highestSeenByTopic[topicId] = @highestSeen
unless Object.isEmpty(newTimings)
$.ajax '/topics/timings'
data:
timings: newTimings
topic_time: @topicTime
highest_seen: @highestSeen
topic_id: topicId
cache: false
type: 'POST'
headers:
'X-SILENCE-LOGGER': 'true'
@topicTime = 0
@lastFlush = 0
tick: ->
# If the user hasn't scrolled the browser in a long time, stop tracking time read
sinceScrolled = new Date().getTime() - @lastScrolled
if sinceScrolled > @PAUSE_UNLESS_SCROLLED
@reset()
return
diff = new Date().getTime() - @lastTick
@lastFlush += diff
@lastTick = new Date().getTime()
@flush() if @lastFlush > (Discourse.SiteSettings.flush_timings_secs * 1000)
# Don't track timings if we're not in focus
return unless Discourse.get("hasFocus")
@topicTime += diff
docViewTop = $(window).scrollTop() + $('header').height()
docViewBottom = docViewTop + $(window).height()
Object.keys @timings, (id) =>
$element = $(id)
if ($element.length == 1)
elemTop = $element.offset().top
elemBottom = elemTop + $element.height()
# If part of the element is on the screen, increase the counter
if (docViewTop <= elemTop <= docViewBottom) or (docViewTop <= elemBottom <= docViewBottom)
timing = @timings[id]
timing.time = timing.time + diff