event.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* eslint-disable
  2. camelcase,
  3. max-len,
  4. no-return-assign,
  5. no-unused-vars,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS102: Remove unnecessary code created because of implicit returns
  12. * DS207: Consider shorter variations of null checks
  13. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  14. */
  15. import moment from 'moment'
  16. import App from '../base'
  17. import '../modules/localStorage'
  18. import { sendMB } from '../infrastructure/event-tracking'
  19. import { debugConsole } from '@/utils/debugging'
  20. const CACHE_KEY = 'mbEvents'
  21. // keep track of how many heartbeats we've sent so we can calculate how
  22. // long wait until the next one
  23. let heartbeatsSent = 0
  24. let nextHeartbeat = new Date()
  25. App.factory('eventTracking', [
  26. '$http',
  27. 'localStorage',
  28. function ($http, localStorage) {
  29. const _getEventCache = function () {
  30. let eventCache = localStorage(CACHE_KEY)
  31. // Initialize as an empy object if the event cache is still empty.
  32. if (eventCache == null) {
  33. eventCache = {}
  34. localStorage(CACHE_KEY, eventCache)
  35. }
  36. return eventCache
  37. }
  38. const _eventInCache = function (key) {
  39. const curCache = _getEventCache()
  40. return curCache[key] || false
  41. }
  42. const _addEventToCache = function (key) {
  43. const curCache = _getEventCache()
  44. curCache[key] = true
  45. return localStorage(CACHE_KEY, curCache)
  46. }
  47. const _sendEditingSessionHeartbeat = segmentation =>
  48. $http({
  49. url: `/editingSession/${window.project_id}`,
  50. method: 'PUT',
  51. data: { segmentation },
  52. headers: {
  53. 'X-CSRF-Token': window.csrfToken,
  54. },
  55. })
  56. return {
  57. send(category, action, label, value) {
  58. return ga('send', 'event', category, action, label, value)
  59. },
  60. sendGAOnce(category, action, label, value) {
  61. if (!_eventInCache(action)) {
  62. _addEventToCache(action)
  63. return this.send(category, action, label, value)
  64. }
  65. },
  66. editingSessionHeartbeat(segmentationCb = () => {}) {
  67. debugConsole.log('[Event] heartbeat trigger')
  68. // If the next heartbeat is in the future, stop
  69. if (nextHeartbeat > new Date()) return
  70. const segmentation = segmentationCb()
  71. debugConsole.log('[Event] send heartbeat request', segmentation)
  72. _sendEditingSessionHeartbeat(segmentation)
  73. heartbeatsSent++
  74. // send two first heartbeats at 0 and 30s then increase the backoff time
  75. // 1min per call until we reach 5 min
  76. const backoffSecs =
  77. heartbeatsSent <= 2
  78. ? 30
  79. : heartbeatsSent <= 6
  80. ? (heartbeatsSent - 2) * 60
  81. : 300
  82. nextHeartbeat = moment().add(backoffSecs, 'seconds').toDate()
  83. },
  84. sendMB,
  85. sendMBSampled(key, segmentation, rate = 0.01) {
  86. if (Math.random() < rate) {
  87. this.sendMB(key, segmentation)
  88. }
  89. },
  90. sendMBOnce(key, segmentation) {
  91. if (!_eventInCache(key)) {
  92. _addEventToCache(key)
  93. this.sendMB(key, segmentation)
  94. }
  95. },
  96. eventInCache(key) {
  97. return _eventInCache(key)
  98. },
  99. }
  100. },
  101. ])
  102. export default $('.navbar a').on('click', function (e) {
  103. const href = $(e.target).attr('href')
  104. if (href != null) {
  105. return ga('send', 'event', 'navigation', 'top menu bar', href)
  106. }
  107. })