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

360 lines
13 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 genreSelector = new context.JK.GenreSelector(app);
var autoComplete = null;
var userNames = [];
var userIds = [];
var MAX_GENRES = 1;
// for unit tests
function loadGenres() {
return genreSelector.loadGenres();
}
// for unit tests
function getGenreSelector() {
return genreSelector;
}
function beforeShow(data) {
userNames = [];
userIds = [];
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.first_name + ' ' + this.last_name);
userIds.push(this.id);
});
// Hook up the autocomplete.
var autoCompleteOptions = {
lookup: { suggestions: userNames, data: userIds },
onSelect: addInvitation
};
if (!autoComplete) {
autoComplete = $('#friend-input').autocomplete(autoCompleteOptions);
} else {
autoComplete.setOptions(autoCompleteOptions);
}
});
}
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();
}
else {
$('#friend-input').select();
context.alert('Invitation already exists for this musician.');
}
}
function removeInvitation(evt) {
$(evt.currentTarget).closest('.invitation').remove();
}
function resetForm() {
var $form = $('#create-session-form');
$('textarea[name="description"]', $form).val('');
genreSelector.reset();
}
function validateForm() {
var errors = [];
var $form = $('#create-session-form');
// Description can't be empty
var description = $('#description').val();
if (!description) {
errors.push(['#description', "Please enter a description."]);
}
var genres = genreSelector.getSelectedGenres();
if (genres.length === 0) {
errors.push(['#genre-list', "Please select a genre."]);
}
if (genres.length > MAX_GENRES) {
errors.push(['#genre-list', "No more than " + MAX_GENRES + "genres are allowed."]);
}
return (errors.length) ? errors : null;
}
function submitForm(evt) {
evt.preventDefault();
var formErrors = validateForm();
if (formErrors) {
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.genres = genreSelector.getSelectedGenres();
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();
}
// FIXME TODO:
// This code is duplicated in sessionModel.js -- refactor
// 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.
var track = { instrument_id: "electric guitar", sound: "stereo" };
if (context.JK.userMe.instruments && context.JK.userMe.instruments.length) {
track = {
instrument_id: context.JK.userMe.instruments[0].instrument_id,
sound: "stereo"
};
}
data.tracks = [ track ]; //getTracks();
var jsonData = JSON.stringify(data);
var url = "/api/sessions";
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: url,
processData:false,
data: jsonData,
success: function(response) {
resetForm();
var newSessionId = response.id;
createInvitations(newSessionId, function() {
context.location = '#/session/' + newSessionId;
});
},
error: app.ajaxError
});
return false;
}
function getTracks() {
var trackIds = context.jamClient.SessionGetIDs();
var allTracks = context.jamClient.SessionGetControlState(trackIds);
var localMusicTracks = [];
var i;
var instruments = [];
var localTrackExists = false;
// get client's tracks
for (i=0; i < allTracks.length; i++) {
if (allTracks[i].group_id === 2) {
localMusicTracks.push(allTracks[i]);
// check if local track config exists
if (allTracks[i].instrument_id !== '') {
localTrackExists = true;
}
}
}
var trackObjects = [];
// FIXME TODO - context.JK.userMe contains current user already.
// get most proficient instrument from API if no local track config exists
if (!localTrackExists) {
$.ajax({
async: false,
url: '/api/users/' + context.JK.currentUserId
}).done(function(user) {
if ("instruments" in user) {
instruments = user.instruments;
var track = {};
track.instrument_id = instruments[0].instrument_id;
track.sound = "stereo";
trackObjects.push(track);
}
}).fail(app.ajaxError);
}
// use all tracks previously configured
else {
for (i=0; i < localMusicTracks.length; i++) {
var track = {};
track.instrument_id = localMusicTracks[i].instrument_id;
if (localMusicTracks[i].stereo) {
track.sound = "stereo";
}
else {
track.sound = "mono";
}
trackObjects.push(track);
}
}
return trackObjects;
}
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);
// 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 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() {
genreSelector.initialize('Choose up to ' + MAX_GENRES + ' genres', MAX_GENRES, $('#create-session-form'));
events();
loadBands();
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;
this.loadGenres = loadGenres;
this.getGenreSelector = getGenreSelector;
return this;
};
})(window,jQuery);