jam-cloud/app/assets/javascripts/createSession.js

507 lines
21 KiB
JavaScript

(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 = new context.JK.FriendSelectorDialog(app, friendSelectorCallback);
var invitationDialog = new context.JK.InvitationDialog(app);
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').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).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).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("<ul class='error-text'><li>Description is required</li></ul>");
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("<ul class='error-text'><li>You must select a genre.</li></ul>");
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("<ul class='error-text'><li>You must accept the JamKazam Terms of Service.</li></ul>");
isValid = false;
}
else {
$('#divIntellectualProperty').removeClass("error");
}
return isValid;
}
function submitForm(evt) {
evt.preventDefault();
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;
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);
},
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;
$('#selected-friends .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() {
$('#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);
});
$('#btn-email-invitation').click(function() {
$('#invitation-textarea-container').show();
$('#invitation-checkbox-container').hide();
$('#btn-send-invitation').show();
$('#btn-next-invitation').hide();
invitationDialog.showDialog();
});
$('#btn-gmail-invitation').click(function() {
$('#invitation-textarea-container').hide();
$('#invitation-checkbox-container').show();
$('#btn-send-invitation').hide();
$('#btn-next-invitation').show();
invitationDialog.showDialog();
$('#invitation-checkboxes').html('<div style="text-align: center; margin-top: 100px;">Loading your contacts...</div>');
window._oauth_callback = function() {
window._oauth_win.close();
window._oauth_win = null;
window._oauth_callback = null;
$.ajax({
type: "GET",
url: "/gmail_contacts",
success: function(response) {
$('#invitation-checkboxes').html('');
for (var i in response) {
$('#invitation-checkboxes').append("<label><input type='checkbox' class='invitation-checkbox' data-email='" + response[i] + "' /> " + response[i] + "</label>");
}
$('.invitation-checkbox').change(function() {
var checkedBoxes = $('.invitation-checkbox:checkbox:checked');
var emails = '';
for (var i = 0; i < checkedBoxes.length; i++) {
emails += $(checkedBoxes[i]).data('email') + ', ';
}
emails = emails.replace(/, $/, '');
$('#txt-emails').val(emails);
});
},
error: function() {
$('#invitation-checkboxes').html("Load failed");
}
});
};
window._oauth_win = window.open("/auth/google_login", "_blank", "height=500,width=500,menubar=no,resizable=no,status=no");
});
$('#btn-facebook-invitation').click(function() {
/*
$('#invitation-textarea-container').hide();
$('#invitation-checkbox-container').show();
$('#btn-send-invitation').hide();
$('#btn-next-invitation').show();
invitationDialog.showDialog();
$('#invitation-checkboxes').html('<div style="text-align: center; margin-top: 100px;">Loading your contacts...</div>');
*/
window._oauth_callback = function() {
window._oauth_win.close();
window._oauth_win = null;
window._oauth_callback = null;
/*
$.ajax({
type: "GET",
url: "/gmail_contacts",
success: function(response) {
$('#invitation-checkboxes').html('');
for (var i in response) {
$('#invitation-checkboxes').append("<label><input type='checkbox' class='invitation-checkbox' data-email='" + response[i] + "' /> " + response[i] + "</label>");
}
$('.invitation-checkbox').change(function() {
var checkedBoxes = $('.invitation-checkbox:checkbox:checked');
var emails = '';
for (var i = 0; i < checkedBoxes.length; i++) {
emails += $(checkedBoxes[i]).data('email') + ', ';
}
emails = emails.replace(/, $/, '');
$('#txt-emails').val(emails);
});
},
error: function() {
$('#invitation-checkboxes').html("Load failed");
}
});
*/
};
window._oauth_win = window.open("/auth/facebook_login", "_blank", "height=500,width=500,menubar=no,resizable=no,status=no");
});
$('#btn-next-invitation').click(function() {
$('#invitation-textarea-container').show();
$('#invitation-checkbox-container').hide();
$('#btn-send-invitation').show();
$('#btn-next-invitation').hide();
});
// 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();
}
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() {
friendSelectorDialog.initialize();
invitationDialog.initialize();
events();
loadBands();
loadSessionSettings();
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);