(function(context,$) { "use strict"; context.JK = context.JK || {}; context.JK.CreateSessionScreen = function(app) { var logger = context.JK.logger; var realtimeMessaging = context.JK.JamServer; var autoComplete = null; var usernames = []; var userids = []; /* Message from Seth on sequence for creating/joining sessions: 02:31:46 PM) Seth Call: sequence: (02:31:53 PM) Seth Call: LOGIN websocket (get your client_id) (02:32:02 PM) Seth Call: CRETAE SESSION (02:32:09 PM) Seth Call: CREATE PARTICIPANT (pass in client_id) (02:32:12 PM) Seth Call: that's it for client 1 (02:32:13 PM) Seth Call: client 2 (02:32:20 PM) Seth Call: LOGIN WEBSOCKET (get your client_id) (02:32:29 PM) Seth Call: CREATE PARTICIPANT(pass in client_id for client2) (02:32:31 PM) Seth Call: that's it (02:32:43 PM) Seth Call: USER_JOINED_MUSIC_SESSION is an event from the server (02:32:52 PM) Seth Call: and LOGIN_MUSIC_SESSION is deprecated/junk */ function beforeShow(data) { usernames = []; userids = []; resetForm(); } /** * Reset form to initial state. */ function resetForm() { var $form = $('#create-session-form'); $('textarea[name="description"]', $form).val(''); } function afterShow(data) { // TODO: This won't work in the long-term. We'll need to provide // a handlers which accepts some characters and only returns users // who are musicians who match that input string. Once we get there, // we could just use the ajax functionality of the autocomplete plugin. // // But for now: // Load the users list into our local array for autocomplete. $.ajax({ type: "GET", url: "/api/users" }).done(function(response) { $.each(response, function() { usernames.push(this.name); userids.push(this.id); }); // Hook up the autocomplete. var autoCompleteOptions = { lookup: {suggestions:usernames, data: userids}, onSelect: addInvitation }; if (!(autoComplete)) { autoComplete = $('#invitations').autocomplete(autoCompleteOptions); } else { autoComplete.setOptions(autoCompleteOptions); } }); } function addInvitation(value, data) { var username = value; var userid = data; var template = $('#template-added-invitation').html(); // TODO: cache this var inviteHtml = context.JK.fillTemplate(template, {userId: userid, userName: username}); $('#added-invitations').append(inviteHtml); $('#invitations').select(); } /** * Validate the form, returning a list of errors. */ function validateForm() { var errors = []; var $form = $('#create-session-form'); // Genres var genresCount = $('select[name="genres"]', $form).find(':selected').length; if (genresCount === 0) { errors.push(['select[name="genres"]', "Please select at least one genre."]); } if (genresCount > 3) { errors.push(['select[name="genres"]', "Please select no more than three genres."]); } // Description can't be empty var description = $('textarea[name="description"]').val(); if (!description) { errors.push(['textarea[name="description"]', "Please enter a description."]); } return (errors.length) ? errors : null; } function submitForm(evt) { evt.preventDefault(); var formErrors = validateForm(); if (formErrors) { app.notify({ title: "Form Problems", text: JSON.stringify(formErrors) }); return false; } var $this = $(evt.currentTarget); logger.debug($this.length); var data = $this.formToObject(); data.client_id = app.clientId; data.as_musician = true; data.legal_terms = true; // this overrides the default of 'on', which isn't satisfying our concept of boolean if (typeof(data.genres) === "string") { data.genres = [data.genres]; } // FIXME: Hard-code tracks for now. Needs to default to: // 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. data.tracks = [ { instrument_id: "electric guitar", sound: "mono" }, { instrument_id: "keyboard", sound: "mono" } ]; // music_session["musician_access"].should be_true // music_session["invitations"].should == [] // music_session["fan_invitations"].should == [] // music_session["approval_required"].should be_false // music_session["fan_chat"].should be_true // music_session["fan_access"].should be_true // music_session["participants"].length.should == 1 // participant = music_session["participants"][0] // participant["ip_address"].should == client.ip_address // participant["client_id"].should == client.client_id // participant["tracks"].length.should == 1 // track = participant["tracks"][0] // track["instrument_id"].should == "electric guitar" // track["sound"].should == "mono" var url = "/api/sessions"; $.ajax({ type: "POST", dataType: "json", contentType: 'application/json', url: url, processData:false, data: JSON.stringify(data), success: function(response) { var newSessionId = response.id; createInvitations(newSessionId, function() { context.location = '#/session/' + newSessionId; }); }, error: app.ajaxError }); return false; } function createInvitations(sessionId, onComplete) { var callCount = 0; $('#added-invitations .invitation').each(function(index, invitation) { callCount++; 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(); } function events() { $('#create-session-form').submit(submitForm); $('#added-invitations').on("click", ".invitation span", removeInvitation); $('#genre-list-header').on("click", toggleGenreBox); $('#genre-list-arrow').on("click", toggleGenreBox); $('#musician-access').change(toggleMusicianAccess); $('#fan-access').change(toggleFanAccess); } function removeInvitation(evt) { $(evt.currentTarget).closest('.invitation').remove(); } function toggleMusicianAccess() { var value = $("#musician-access option:selected").val(); if (value == "private") { $("[name='musician-access-option']").attr('disabled', 'disabled'); $("[name='musician-access-option']").parent().addClass("op50"); } else { $("[name='musician-access-option']").removeAttr('disabled'); $("[name='musician-access-option']").parent().removeClass("op50"); } } function toggleFanAccess() { var value = $("#fan-access option:selected").val(); if (value == "private") { $("[name='fan-chat-option']").attr('disabled', 'disabled'); $("[name='fan-chat-option']").parent().addClass("op50"); } else { $("[name='fan-chat-option']").removeAttr('disabled'); $("[name='fan-chat-option']").parent().removeClass("op50"); } } function loadGenres() { var url = "/api/genres"; $.ajax({ type: "GET", url: url, success: genresLoaded }); } function genresLoaded(response) { $.each(response, function() { var template = $('#template-genre-option').html(); var genreOptionHtml = context.JK.fillTemplate(template, {value: this.id, label: this.description}); $('#genre-list-items').append(genreOptionHtml); //$('#genre-list-items').append("