event-tracking.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import sessionStorage from '../infrastructure/session-storage'
  2. import getMeta from '@/utils/meta'
  3. const CACHE_KEY = 'mbEvents'
  4. function alreadySent(key) {
  5. const eventCache = sessionStorage.getItem(CACHE_KEY) || {}
  6. return !!eventCache[key]
  7. }
  8. function markAsSent(key) {
  9. const eventCache = sessionStorage.getItem(CACHE_KEY) || {}
  10. eventCache[key] = true
  11. sessionStorage.setItem(CACHE_KEY, eventCache)
  12. }
  13. export function send(category, action, label, value) {
  14. if (typeof window.ga === 'function') {
  15. window.ga('send', 'event', category, action, label, value)
  16. }
  17. }
  18. export function sendOnce(category, action, label, value) {
  19. if (alreadySent(category)) return
  20. if (typeof window.ga !== 'function') return
  21. window.ga('send', 'event', category, action, label, value)
  22. markAsSent(category)
  23. }
  24. export function sendMB(key, segmentation = {}) {
  25. if (!segmentation.page) {
  26. segmentation.page = window.location.pathname
  27. }
  28. sendBeacon(key, segmentation)
  29. if (typeof window.gtag !== 'function') return
  30. if (['paywall-click', 'paywall-prompt', 'plans-page-click'].includes(key)) {
  31. window.gtag('event', key, segmentation)
  32. }
  33. }
  34. export function sendMBOnce(key, segmentation = {}) {
  35. if (alreadySent(key)) return
  36. sendMB(key, segmentation)
  37. markAsSent(key)
  38. }
  39. export function sendMBSampled(key, body = {}, rate = 0.01) {
  40. if (Math.random() < rate) {
  41. sendMB(key, body)
  42. }
  43. }
  44. const sentOncePerPageLoad = new Set()
  45. export function sendMBOncePerPageLoad(key, segmentation = {}) {
  46. if (sentOncePerPageLoad.has(key)) return
  47. sendMB(key, segmentation)
  48. sentOncePerPageLoad.add(key)
  49. }
  50. // Use breakpoint @screen-xs-max from less:
  51. // @screen-xs-max: (@screen-sm-min - 1);
  52. // @screen-sm-min: @screen-sm;
  53. // @screen-sm: 768px;
  54. export const isSmallDevice = window.screen.width < 768
  55. function sendBeacon(key, data) {
  56. if (!navigator || !navigator.sendBeacon) return
  57. if (!getMeta('ol-ExposedSettings').isOverleaf) return
  58. data._csrf = getMeta('ol-csrfToken')
  59. const blob = new Blob([JSON.stringify(data)], {
  60. type: 'application/json; charset=UTF-8',
  61. })
  62. try {
  63. navigator.sendBeacon(`/event/${key}`, blob)
  64. } catch (error) {
  65. // Ignored. There's a range of browser for which `navigator.sendBeacon` is available but
  66. // will throw an error if it's called with an unacceptable mime-typed Blob as the data.
  67. }
  68. }