245 lines
8.8 KiB
JavaScript
245 lines
8.8 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 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);
|
|
}
|
|
|
|
function removeInvitation(evt) {
|
|
$(evt.currentTarget).closest('.invitation').remove();
|
|
}
|
|
|
|
function genresLoaded(response) {
|
|
var options = [];
|
|
var optionTemplate = $('#template-genre-option').html();
|
|
$.each(response, function() {
|
|
var d = {value: this.id, label: this.description};
|
|
var opt = context.JK.fillTemplate(optionTemplate, d);
|
|
options.push(opt);
|
|
});
|
|
$('#create-session-form select[name="genres"]').html(options.join(''));
|
|
}
|
|
|
|
function loadGenres() {
|
|
var url = "/api/genres";
|
|
$.ajax({
|
|
type: "GET",
|
|
url: url,
|
|
success: genresLoaded
|
|
});
|
|
}
|
|
|
|
function initialize() {
|
|
events();
|
|
loadGenres();
|
|
var screenBindings = { 'afterShow': afterShow, 'beforeShow': beforeShow };
|
|
app.bindScreen('createSession', screenBindings);
|
|
}
|
|
|
|
// Expose publics
|
|
this.initialize = initialize;
|
|
this.resetForm = resetForm;
|
|
this.submitForm = submitForm;
|
|
this.loadGenres = loadGenres;
|
|
this.validateForm = validateForm;
|
|
|
|
return this;
|
|
};
|
|
|
|
})(window,jQuery); |