<commit_before>L, messagebar, events, DBAPI <- define <[
  leaflet messagebar util/events util/dbapi
]>


# Member check-in database endpoint.
const BT_CHECKIN_ENDPOINT = "blitzertracker/checkins"

# Time since the last check-in during which an user is considered
# to be online.
const RECENT_CHECKIN_THRESHOLD = 270s * 1000ms

# Interval between database queries for check-in updates.
const CHECKIN_QUERY_INTERVAL = 90s * 1000ms


class User implements events.PausableEventTarget.prototype
  (@username) ->
    events.PausableEventTarget.call this
    @activityCheckInterval = setInterval @~checkStatus, CHECKIN_QUERY_INTERVAL
    @checkStatus!

  # Set a property and dispatch an event informing the change.
  updateProperty: (name, newValue, eventName) !->
    oldValue = @[name]
    @[name] = newValue
    @dispatchEvent new events.SimpleEvent eventName,
      detail: {oldValue, newValue}

  # Set the location property if unset or the new value differs
  # from the current one and dispatch an event informing the change.
  setLocation: (newLocation) !->
    # Normalize the location into Leaflet's `LatLng` object (note
    # that the constructor form doesn't support all the different
    # representations).
    newLocation = L.latLng newLocation
    if not newLocation.equals @location
      @updateProperty \location, newLocation, \locationchange

  # Set the status property if unset or the new value differs
  # from the current one and dispatch an event informing the change.
  setStatus: (newStatus) !->
    if not @status? or
       newStatus isnt @status
      @updateProperty \status, newStatus, \statuschange

  # Fetch the user's status from the database, updating the status
  # property accordingly.
  checkStatus: !->
    DBAPI \GET, "#{BT_CHECKIN_ENDPOINT}/#{@username}",
      void
    , (event) !~>
      {lastCheckin} = JSON.parse event.target.responseText
      @checkinDate = new Date lastCheckin
      if (Date.now! - @checkinDate.getTime!) <= RECENT_CHECKIN_THRESHOLD
        @setStatus \online
      else
        @setStatus \offline
    , (event) !~>
      @setStatus \unknown
      if event.target.status is 404
        # Just stop checking.
        clearInterval @activityCheckInterval<commit_msg>Bind user status change to the last access property<commit_after>L, messagebar, events, DBAPI <- define <[
  leaflet messagebar util/events util/dbapi
]>


# Member check-in database endpoint.
const BT_CHECKIN_ENDPOINT = "blitzertracker/checkins"

# Time since the last check-in during which an user is considered
# to be online.
const RECENT_CHECKIN_THRESHOLD = 270s * 1000ms

# Interval between database queries for check-in updates.
const CHECKIN_QUERY_INTERVAL = 90s * 1000ms


class User implements events.PausableEventTarget.prototype
  (@username) ->
    events.PausableEventTarget.call this
    # Update the status whenever the last access timestamp changes.
    @addEventListener \lastaccesschange @updateStatusFromLastAccess
    # Check the last access timestamp now and then.
    @activityCheckInterval = setInterval @~checkStatus, CHECKIN_QUERY_INTERVAL
    @checkStatus!

  # Set a property and dispatch an event informing the change.
  updateProperty: (name, newValue, eventName) !->
    oldValue = @[name]
    @[name] = newValue
    @dispatchEvent new events.SimpleEvent eventName,
      detail: {oldValue, newValue}

  # Set the location property if unset or the new value differs
  # from the current one and dispatch an event informing the change.
  setLocation: (newLocation) !->
    # Normalize the location into Leaflet's `LatLng` object (note
    # that the constructor form doesn't support all the different
    # representations).
    newLocation = L.latLng newLocation
    if not newLocation.equals @location
      @updateProperty \location, newLocation, \locationchange

  # Set the status property if unset or the new value differs
  # from the current one and dispatch an event informing the change.
  setStatus: (newStatus) !->
    if not @status? or
       newStatus isnt @status
      @updateProperty \status, newStatus, \statuschange

  # Set the last access timestamp property if unset or the new value
  # differs from the current one and dispatch an event informing the
  # change.
  setLastAccessTimestamp: (newTimestamp) !->
    if newTimestamp.getTime! isnt @lastAccess?getTime!
      @updateProperty \lastAccess, newTimestamp, \lastaccesschange

  # Unset the last access timestamp property and dispatch an event
  # informing the change.
  unsetLastAccessTimestamp: !->
    if @lastAccess?
      @updateProperty \lastAccess, null, \lastaccesschange

  # Update the status property based on the last access timestamp.
  updateStatusFromLastAccess: !->
    if not @lastAccess?
      @setStatus void
    else if (Date.now! - @lastAccess.getTime!) <= RECENT_CHECKIN_THRESHOLD
      @setStatus \online
    else
      @setStatus \offline

  # Fetch the user's status from the database, updating the status
  # property accordingly.
  checkStatus: !->
    DBAPI \GET, "#{BT_CHECKIN_ENDPOINT}/#{@username}",
      void
    , (event) !~>
      {lastCheckin} = JSON.parse event.target.responseText
      @setLastAccessTimestamp new Date lastCheckin
    , (event) !~>
      @unsetLastAccessTimestamp!
      if event.target.status is 404
        # Just stop checking.
        clearInterval @activityCheckInterval
{'fraction_non_alphanumeric': 0.07652206293055297, 'fraction_numerical': 0.005957922174641594, 'mean_word_length': 3.6032562125107113, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4513275', 'n_tokens_mistral': 1553, 'n_tokens_neox': 1486, 'n_words': 529}