(function(context,$) { "use strict"; context.JK = context.JK || {}; context.JK.CreateSessionScreen = function(app) { var logger = context.JK.logger; var realtimeMessaging = context.JK.JamServer; var friendSelectorDialog = null; var invitationDialog = null; var autoComplete = null; var userNames = []; var userIds = []; var userPhotoUrls = []; var MAX_GENRES = 1; var selectedFriendIds = {}; var sessionSettings = {}; function beforeShow(data) { userNames = []; userIds = []; userPhotoUrls = []; context.JK.GenreSelectorHelper.render('#create-session-genre'); resetForm(); } function afterShow(data) { $.ajax({ type: "GET", url: "/api/users/" + context.JK.currentUserId + "/friends", async: false }).done(function(response) { $.each(response, function() { userNames.push(this.name); userIds.push(this.id); userPhotoUrls.push(this.photo_url); }); // var autoCompleteOptions = { // lookup: { suggestions: userNames, data: userIds }, // onSelect: addInvitation // }; // if (!autoComplete) { // autoComplete = $('#friend-input').autocomplete(autoCompleteOptions); // } // else { // autoComplete.setOptions(autoCompleteOptions); // } }); // var autoCompleteOptions = { // serviceUrl: "/api/users/" + context.JK.currentUserId + "/friends", // minChars: 3, // dataType: 'jsonp', // transformResult: function(response) { // logger.debug("transforming..."); // logger.debug("response.length=" + response.length); // return { // suggestions: $.map(response, function(dataItem) { // return { value: dataItem.id, data: dataItem.name }; // }) // }; // }, // onSelect: addInvitation // }; // if (!autoComplete) { // autoComplete = $('#friend-input').autocomplete(autoCompleteOptions); // } // else { // logger.debug("here2"); // autoComplete.setOptions(autoCompleteOptions); // } } function friendSelectorCallback(newSelections) { var keys = Object.keys(newSelections); for (var i=0; i < keys.length; i++) { addInvitation(newSelections[keys[i]].userName, newSelections[keys[i]].userId); } } function addInvitation(value, data) { if ($('#selected-friends div[user-id=' + data + ']').length === 0) { var template = $('#template-added-invitation').html(); var invitationHtml = context.JK.fillTemplate(template, {userId: data, userName: value}); $('#selected-friends').append(invitationHtml); $('#friend-input').select(); selectedFriendIds[data] = true; } else { $('#friend-input').select(); context.alert('Invitation already exists for this musician.'); } } function removeInvitation(evt) { delete selectedFriendIds[$(evt.currentTarget).parent().attr('user-id')]; $(evt.currentTarget).closest('.invitation').remove(); } function resetForm() { $('#intellectual-property').iCheck('uncheck').attr('checked', false); var $form = $('#create-session-form'); var description = sessionSettings.hasOwnProperty('description') ? sessionSettings.description : ''; $('textarea[name="description"]', $form).val(description); var genre = sessionSettings.hasOwnProperty('genres') && sessionSettings.genres.length > 0 ? sessionSettings.genres[0].id : ''; context.JK.GenreSelectorHelper.reset('#create-session-genre', genre); var musician_access = sessionSettings.hasOwnProperty('musician_access') ? sessionSettings.musician_access : true; $('#musician-access option[value=' + musician_access + ']').attr('selected', 'selected'); toggleMusicianAccess(); if (musician_access) { var approval_required = sessionSettings.hasOwnProperty('approval_required') ? sessionSettings.approval_required : false; $('#musician-access-option-' + approval_required).iCheck('check').attr('checked', 'checked'); } var fan_access = sessionSettings.hasOwnProperty('fan_access') ? sessionSettings.fan_access : true; $('#fan-access option[value=' + fan_access + ']').attr('selected', 'selected'); toggleFanAccess(); if (fan_access) { var fan_chat = sessionSettings.hasOwnProperty('fan_chat') ? sessionSettings.fan_chat : false; $('#fan-chat-option-' + fan_chat).iCheck('check').attr('checked', 'checked'); } // Should easily be able to grab other items out of sessionSettings and put them into the appropriate ui elements. } function validateForm() { //var errors = []; var isValid = true; var $form = $('#create-session-form'); // Description can't be empty var description = $('#description').val(); if (!description) { $('#divDescription .error-text').remove(); $('#divDescription').addClass("error"); $('#description').after(""); isValid = false; } else { $('#divDescription').removeClass("error"); } var genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre'); if (genres.length === 0) { $('#divGenre .error-text').remove(); $('#divGenre').addClass("error"); $('#create-session-genre').after(""); isValid = false; } else { $('#divGenre').removeClass("error"); } // if (genres.length > MAX_GENRES) { // errors.push(['#genre-list', "No more than " + MAX_GENRES + "genres are allowed."]); // } var intellectualPropertyChecked = $('#intellectual-property').is(':checked'); if (!intellectualPropertyChecked) { $('#divIntellectualProperty .error-text').remove(); $('#divIntellectualProperty').addClass("error"); $('#divTerms').after(""); isValid = false; } else { $('#divIntellectualProperty').removeClass("error"); } return isValid; } function submitForm(evt) { evt.preventDefault(); // If user hasn't completed FTUE - do so now. if (!(context.jamClient.FTUEGetStatus())) { app.afterFtue = function() { submitForm(evt); }; app.layout.showDialog('ftue'); return; } var isValid = validateForm(); if (!isValid) { // app.notify({ // title: "Validation Errors", // text: JSON.stringify(formErrors) // }); return false; } var data = {}; data.client_id = app.clientId; data.description = $('#description').val(); data.as_musician = true; data.legal_terms = true; // this overrides the default of 'on', which isn't satisfying our concept of boolean data.intellectual_property = $('#intellectual-property').is(':checked'); data.genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre'); data.musician_access = $('#musician-access option:selected').val() === "true" ? true : false; data.approval_required = $("input[name='musician-access-option']:checked").val() === "true" ? true : false; data.fan_access = $('#fan-access option:selected').val() === "true" ? true : false; data.fan_chat = $("input[name='fan-chat-option']:checked").val() === "true" ? true : false; if ($('#band-list option:selected').val() !== '') { data.band = $('#band-list option:selected').val(); } // 1. If no previous session data, a single stereo track with the // top instrument in the user's profile. // 2. Otherwise, use the tracks from the last created session. // Defaulting to 1st instrument in profile always at the moment. data.tracks = context.JK.TrackHelpers.getUserTracks(context.jamClient); var jsonData = JSON.stringify(data); console.log("session data=" + jsonData); $('#btn-create-session').addClass('button-disabled'); $('#btn-create-session').bind('click', false); var url = "/api/sessions"; $.ajax({ type: "POST", dataType: "json", contentType: 'application/json', url: url, processData:false, data: jsonData, success: function(response) { var newSessionId = response.id; 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. // This is an extra xhr call, but it keeps things to a single codepath 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); $('#btn-create-session').removeClass('button-disabled'); $('#btn-create-session').unbind('click', false); } }); return false; } 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, receiver: invite_id }; $.ajax({ type: "POST", url: "/api/invitations", data: invite }).done(function(response) { callCount--; }).fail(app.ajaxError); }); // TODO - this is the second time I've used this pattern. // refactor to make a common utility for this. function checker() { if (callCount === 0) { onComplete(); } else { context.setTimeout(checker, 10); } } checker(); return totalInvitations; } function events() { $('#btn-create-session').on("click", submitForm); $('#selected-friends').on("click", ".invitation a", removeInvitation); $('#musician-access').change(toggleMusicianAccess); $('#fan-access').change(toggleFanAccess); $('#btn-choose-friends').click(function() { friendSelectorDialog.showDialog(selectedFriendIds); }); $('div[layout-id="createSession"] .btn-email-invitation').click(function() { invitationDialog.showEmailDialog(); }); $('div[layout-id="createSession"] .btn-gmail-invitation').click(function() { invitationDialog.showGoogleDialog(); }); $('div[layout-id="createSession"] .btn-facebook-invitation').click(function() { invitationDialog.showFacebookDialog(); }); // friend input focus $('#friend-input').focus(function() { $(this).val(''); }); // friend input blur $('#friend-input').blur(function() { $(this).val('Type a friend\'s name'); }); } function toggleMusicianAccess() { var value = $("#musician-access option:selected").val(); if (value == "false") { $("input[name='musician-access-option']").attr('disabled', 'disabled'); $("input[name='musician-access-option']").parent().addClass("op50"); } else { $("input[name='musician-access-option']").removeAttr('disabled'); $("input[name='musician-access-option']").parent().removeClass("op50"); } } function toggleFanAccess() { var value = $("#fan-access option:selected").val(); if (value == "false") { $("input[name='fan-chat-option']").attr('disabled', 'disabled'); $("input[name='fan-chat-option']").parent().addClass("op50"); } else { $("input[name='fan-chat-option']").removeAttr('disabled'); $("input[name='fan-chat-option']").parent().removeClass("op50"); } } function loadBands() { var url = "/api/users/" + context.JK.currentUserId + "/bands"; $.ajax({ type: "GET", url: url, success: bandsLoaded }); } function bandsLoaded(response) { $.each(response, function() { var template = $('#template-band-option').html(); var bandOptionHtml = context.JK.fillTemplate(template, {value: this.id, label: this.name}); $('#band-list').append(bandOptionHtml); }); } function loadSessionSettings() { var url = "/api/users/" + context.JK.currentUserId + "/session_settings"; $.ajax({ type: "GET", url: url, success: sessionSettingsLoaded }); } function sessionSettingsLoaded(response) { if (response != null) { sessionSettings = response; } resetForm(); } // this exists solely due to a bug in Windows QTWebkit: https://bugreports.qt-project.org/browse/QTBUG-30072 function initializeButtons() { $('div[layout-id="createSession"] .icheckbuttons input').iCheck({ checkboxClass: 'icheckbox_minimal', radioClass: 'iradio_minimal', inheritClass: true }); } function searchFriends(query) { if (query.length < 2) { $('#friend-search-results').empty(); return; } var url = "/api/search?query=" + query + "&userId=" + context.JK.currentUserId; $.ajax({ type: "GET", url: url, success: friendSearchComplete }); } function friendSearchComplete(response) { // reset search results each time $('#friend-search-results').empty(); // loop through each $.each(response.friends, function() { // only show friends who are musicians if (this.musician === true) { var template = $('#template-friend-search-results').html(); var searchResultHtml = context.JK.fillTemplate(template, {userId: this.id, name: this.first_name + ' ' + this.last_name}); $('#friend-search-results').append(searchResultHtml); $('#friend-search-results').attr('style', 'display:block'); } }); } function initialize(invitationDialogInstance, friendSelectorDialogInstance) { friendSelectorDialog = friendSelectorDialogInstance; friendSelectorDialog.setCallback(friendSelectorCallback); invitationDialog = invitationDialogInstance; events(); loadBands(); loadSessionSettings(); initializeButtons(); var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow }; app.bindScreen('createSession', screenBindings); } // Expose publics this.initialize = initialize; this.resetForm = resetForm; this.submitForm = submitForm; this.validateForm = validateForm; this.loadBands = loadBands; this.searchFriends = searchFriends; this.addInvitation = addInvitation; return this; }; })(window,jQuery);