diff --git a/src/js/components/navigator.js b/src/js/components/navigator.js index ea987928a..4484686a5 100644 --- a/src/js/components/navigator.js +++ b/src/js/components/navigator.js @@ -1,5 +1,5 @@ /** -/** + /** * Created by rchyla on 3/10/14. */ @@ -21,7 +21,7 @@ define([ 'js/components/transition', 'js/components/transition_catalog', 'analytics', -], function( +], function ( _, $, Cache, @@ -29,14 +29,30 @@ define([ Mixins, Transition, TransitionCatalog, - analytics + analytics, ) { // Document Title Constants var APP_TITLE = 'NASA/ADS'; var TITLE_SEP = ' - '; + // This function is used to hash the user id before sending it to Analytics + const digestMessage = function (message) { + const crypto = window.crypto || window.msCrypto; + if (!crypto) { + return Promise.reject(new Error('Crypto not available')); + } + // encode as (utf-8) Uint8Array + const msgUi8 = new TextEncoder().encode(message); + + // hash the message + return crypto.subtle.digest('SHA-256', msgUi8).then((hashBuffer) => { + const hashArray = Array.from(new Uint8Array(hashBuffer)); + return hashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); + }); + }; + var Navigator = GenericModule.extend({ - initialize: function(options) { + initialize: function (options) { options = options || {}; this.router = options.router; this.catalog = new TransitionCatalog(); // catalog of nagivation points (later we can build FST) @@ -48,21 +64,36 @@ define([ * @param beehive - the full access instance; we excpect PubSub to be * present */ - activate: function(beehive) { + activate: function (beehive) { this.setBeeHive(beehive); this.storage = beehive.getObject('AppStorage'); var pubsub = this.getPubSub(); pubsub.subscribe(pubsub.NAVIGATE, _.bind(this.navigate, this)); pubsub.subscribe(pubsub.CUSTOM_EVENT, _.bind(this._onCustomEvent, this)); + pubsub.subscribe( + pubsub.USER_ANNOUNCEMENT, + _.bind(this._onUserAnnouncement, this), + ); + }, + + _onUserAnnouncement: function (ev, data) { + if (ev === 'user_signed_in' && typeof data === 'string') { + // the user is signed in, we can associate the user with the session + digestMessage(data).then((userIdHash) => { + analytics('send', 'user_update', { + user_id: userIdHash, + }); + }); + } }, - _onCustomEvent: function(ev, data) { + _onCustomEvent: function (ev, data) { if (ev === 'update-document-title') { this._updateDocumentTitle(data); } }, - _cleanRoute: function(route) { + _cleanRoute: function (route) { const r = route.match(/[#\/]?([^\/]*)\//); if (r && r.length > 1) { return '/' + r[1]; @@ -70,17 +101,17 @@ define([ return route; }, - _setPageAndEmitEvent: _.debounce(function(route, pageName) { - analytics('set', 'page', this._cleanRoute(route)); - analytics('send', 'pageview', { - dimension1: pageName, + _setPageAndEmitEvent: _.debounce(function (route, pageName) { + analytics('send', 'virtual_page_view', { + page_name: pageName, + clean_route: this._cleanRoute(route), }); }, 300), /** * Responds to PubSubEvents.NAVIGATE signal */ - navigate: function(ev, arg1, arg2) { + navigate: function (ev, arg1, arg2) { var defer = $.Deferred(); var self = this; @@ -101,7 +132,7 @@ define([ return defer.resolve().promise(); } - var afterNavigation = _.bind(function() { + var afterNavigation = _.bind(function () { // router can communicate directly with navigator to replace url var replace = !!(transition.replace || (arg1 && arg1.replace)); @@ -116,8 +147,8 @@ define([ // clear any metadata added to head on the previous page $('head') - .find('meta[data-highwire]') - .remove(); + .find('meta[data-highwire]') + .remove(); this._updateDocumentTitle(transition.title); defer.resolve(); }, this); @@ -135,10 +166,10 @@ define([ return defer.promise(); }, - _updateDocumentTitle: function(title) { + _updateDocumentTitle: function (title) { if (_.isUndefined(title) || title === false) return; var currTitle = this.storage.getDocumentTitle(); - var setDocTitle = _.bind(function(t) { + var setDocTitle = _.bind(function (t) { document.title = t === '' ? APP_TITLE : t + TITLE_SEP + APP_TITLE; this.storage.setDocumentTitle(t); }, this); @@ -149,16 +180,16 @@ define([ } }, - handleMissingTransition: function(transition) { + handleMissingTransition: function (transition) { console.error( - "Cannot handle 'navigate' event: " + JSON.stringify(arguments) + "Cannot handle 'navigate' event: " + JSON.stringify(arguments), ); var ps = this.getPubSub(); ps.publish(ps.BIG_FIRE, 'navigation-error', arguments); if (this.catalog.get('404')) ps.publish(ps.NAVIGATE, '404'); }, - handleTransitionError: function(transition, error, args) { + handleTransitionError: function (transition, error, args) { console.error('Error while executing transition', transition, args); console.error(error.stack); var ps = this.getPubSub(); @@ -170,7 +201,7 @@ define([ * Sets the transition inside the catalog; you can pass simplified * list of options or the Transition instance */ - set: function() { + set: function () { if (arguments.length == 1) { if (arguments[1] instanceof Transition) { return this.catalog.add(arguments[1]); @@ -182,7 +213,7 @@ define([ return this.catalog.add( new Transition(endpoint, { execute: arguments[1], - }) + }), ); } if (_.isObject(arguments[1]) && arguments[1].execute) { @@ -191,18 +222,18 @@ define([ throw new Error( 'Himmm, I dont know how to create a catalog rule with this input:', - arguments + arguments, ); } else { // var args = array.slice.call(arguments, 1); throw new Error( 'Himmm, I dont know how to create a catalog rule with this input:', - arguments + arguments, ); } }, - get: function(endpoint) { + get: function (endpoint) { return this.catalog.get(endpoint); }, });