diff --git a/web/app/assets/javascripts/createSession.js b/web/app/assets/javascripts/createSession.js index b3e866f0e..301fa3f64 100644 --- a/web/app/assets/javascripts/createSession.js +++ b/web/app/assets/javascripts/createSession.js @@ -229,7 +229,7 @@ data: jsonData, success: function(response) { var newSessionId = response.id; - createInvitations(newSessionId, function() { + var invitationCount = createInvitations(newSessionId, function() { context.location = '#/session/' + newSessionId; }); // Re-loading the session settings will cause the form to reset with the right stuff in it. @@ -237,6 +237,10 @@ loadSessionSettings(); $('#btn-create-session').removeClass('button-disabled'); $('#btn-create-session').unbind('click', false); + + context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, invitationCount); + + context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create); }, error: function() { app.ajaxError(arguments); @@ -249,8 +253,10 @@ function createInvitations(sessionId, onComplete) { var callCount = 0; + var totalInvitations = 0; $('#selected-friends .invitation').each(function(index, invitation) { callCount++; + totalInvitations++; var invite_id = $(invitation).attr('user-id'); var invite = { music_session: sessionId, @@ -274,6 +280,7 @@ } } checker(); + return totalInvitations; } function events() { @@ -321,7 +328,8 @@ emails += $(checkedBoxes[i]).data('email') + ', '; } emails = emails.replace(/, $/, ''); - $('#txt-emails').val(emails); + // track how many of these came from google + $('#txt-emails').val(emails).data('google_invite_count', checkedBoxes.length); }); }, error: function() { diff --git a/web/app/assets/javascripts/ga.js b/web/app/assets/javascripts/ga.js index 46e05a8c7..8b21bef9b 100644 --- a/web/app/assets/javascripts/ga.js +++ b/web/app/assets/javascripts/ga.js @@ -14,11 +14,24 @@ facebook : "Facebook" } + var sessionCreationTypes = { + create : "Create", + join : "Join" + } + + var invitationTypes = { + email : "Email", + facebook : "Facebook", + google : "Google" + } + var categories = { register : "Register", download : "DownloadClient", - audioTest : "AudioTest" - + audioTest : "AudioTest", + sessionCount : "SessionCount", + sessionMusicians : "SessionMusicians", + invite : "Invite" } function translatePlatformForGA(platform) { @@ -41,6 +54,12 @@ } } + function assertNumber(value) { + if(typeof value != 'number') { + throw "value is not a number: " + JSON.stringify(value); + } + } + function assertOneOf(enumValue, enums){ var found = false; for (var key in enums) { @@ -78,10 +97,39 @@ ga('send', 'event', categories.audioTest, status, normalizedPlatform); } + function trackSessionCount(musicianAccess, fanAccess, invitationCount) { + assertBoolean(musicianAccess); + assertBoolean(fanAccess); + assertNumber(invitationCount); + + var gaMusicianAccess = musicianAccess ? "MusicianPublic" : "MusicianPrivate"; + var gaFanAccess = fanAccess ? "FanPublic" : "FanPrivate"; + + ga('send', 'event', categories.sessionCount, gaMusicianAccess, gaFanAccess, invitationCount); + } + + function trackSessionMusicians(joinOrCreate) { + assertOneOf(joinOrCreate, sessionCreationTypes); + + ga('send', 'event', categories.sessionMusicians, joinOrCreate); + } + + function trackServiceInvitations(invitationType, numInvited) { + assertOneOf(invitationType, invitationTypes); + assertNumber(numInvited); + + ga('send', 'event', categories.invite, invitationType, numInvited); + } + var GA = {}; + GA.SessionCreationTypes = sessionCreationTypes; + GA.InvitationTypes = invitationTypes; GA.trackRegister = trackRegister; GA.trackDownload = trackDownload; GA.trackFTUECompletion = trackFTUECompletion; + GA.trackSessionCount = trackSessionCount; + GA.trackSessionMusicians = trackSessionMusicians; + GA.trackServiceInvitations = trackServiceInvitations; context.JK.GA = GA; diff --git a/web/app/assets/javascripts/invitation.js b/web/app/assets/javascripts/invitation.js index ecfb10598..7f99b6a91 100644 --- a/web/app/assets/javascripts/invitation.js +++ b/web/app/assets/javascripts/invitation.js @@ -1,39 +1,54 @@ (function(context,$) { - "use strict"; + "use strict"; + context.JK = context.JK || {}; + context.JK.InvitationDialog = function(app) { + var logger = context.JK.logger; + var rest = context.JK.Rest(); + + function events() { + $('#btn-send-invitation').click(sendEmail); + } + + function trackGA(emails, googleInviteCount) { + var allInvitations = emails.length; // all email invites, regardless of how they got in the form + var emailInvitations = allInvitations - (googleInviteCount ? googleInviteCount : 0); // take out google invites + context.JK.GA.trackServiceInvitations(context.JK.GA.InvitationTypes.email, emailInvitations); + if (googleInviteCount) { + context.JK.GA.trackServiceInvitations(context.JK.GA.InvitationTypes.google, googleInviteCount); + } + } + + function sendEmail() { + var emails = []; + emails = $('#txt-emails').val().split(','); + + for (var i=0; i < emails.length; i++) { + rest.createInvitation($.trim(emails[i]), $('#txt-message').val()) + .done(function() { + + + }); + } + + trackGA(emails, $('#txt-emails').data('google_invite_count')); + } + + this.showDialog = function() { + clearTextFields(); + } + + function clearTextFields() { + $('#txt-emails').val('').removeData('google_invite_count'); + $('#txt-message').val(''); + } + + this.initialize = function() { + events(); + }; - context.JK = context.JK || {}; - context.JK.InvitationDialog = function(app) { - var logger = context.JK.logger; - var rest = context.JK.Rest(); - function events() { - $('#btn-send-invitation').click(sendEmail); } - function sendEmail() { - var emails = []; - emails = $('#txt-emails').val().split(','); - - for (var i=0; i < emails.length; i++) { - rest.createInvitation($.trim(emails[i]), $('#txt-message').val()) - .done(function() { }); - } - } - - this.showDialog = function() { - clearTextFields(); - } - - function clearTextFields() { - $('#txt-emails').val(''); - $('#txt-message').val(''); - } - - this.initialize = function() { - events(); - }; - } - return this; })(window,jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/sessionModel.js b/web/app/assets/javascripts/sessionModel.js index 5a194cb50..712efbaee 100644 --- a/web/app/assets/javascripts/sessionModel.js +++ b/web/app/assets/javascripts/sessionModel.js @@ -27,6 +27,24 @@ } } + function creatorId() { + if(!currentSession) { + throw "creator is not known" + } + return currentSession.user_id; + } + + function alreadyInSession() { + var inSession = false; + $.each(participants(), function(index, participant) { + if(participant.user.id == context.JK.currentUserId) { + inSession = true; + return false; + } + }); + return inSession; + } + /** * Join the session specified by the provided id. */ @@ -38,10 +56,19 @@ deferred .done(function(){ logger.debug("calling jamClient.JoinSession"); + + if(!alreadyInSession()) { + // on temporary disconnect scenarios, a user may already be in a session when they enter this path + // so we avoid double counting + context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.join); + } + client.JoinSession({ sessionID: sessionId }); refreshCurrentSession(); server.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, refreshCurrentSession); server.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, refreshCurrentSession); + + }) .fail(function() { currentSessionId = null; @@ -320,7 +347,6 @@ dataType: "json", contentType: 'application/json', url: url, - async: true, data: JSON.stringify(data), processData:false }); diff --git a/web/app/assets/javascripts/userSession.js b/web/app/assets/javascripts/userSession.js new file mode 100644 index 000000000..6ff692723 --- /dev/null +++ b/web/app/assets/javascripts/userSession.js @@ -0,0 +1,27 @@ +(function(context,$) { + + "use strict"; + + context.JK = context.JK || {}; + context.JK.UserSession = function(app) { + var logger = context.JK.logger; + var rest = context.JK.Rest(); + var userId; + var user = {}; + var currentUserWatchers = $(); + + function initialize(currentUserId) { + userId = currentUserId; + } + + // called anytime user data is fetched for the current user + function registerCurrentUser(listener) { + currentUserWatchers.add($(listener)); + } + + this.initialize = initialize; + this.registerCurrentUser = registerCurrentUser; + return this; + }; + +})(window,jQuery);