(function (context, $) { "use strict"; context.JK = context.JK || {}; context.JK.AccountSessionProperties = function (app) { var logger = context.JK.logger; var rest = context.JK.Rest(); var sessionId = null; var sessionData = null; var $screen = $("#account-session-properties"); var $inputFiles = $screen.find('#session-select-files'); var $selectedFilenames = $screen.find('#selected-filenames'); var $propertiesBody = null; var $languageList = null; var $recurringModeList = null; var $timezoneList = null; var $startTimeList = null; var $endTimeList = null; var $sessionName = null; var $sessionDescription = null; var $musicianAccess = null; var $fansAccess = null; var $musicNotations = null; var $btnSelectFiles = null; var $uploadSpinner = null; var $dateTimeTBD = null; var $actionBar = null; var ONE_HOUR = 3600 * 1000; var ONE_MINUTE = 60 * 1000; var ONE_DAY = ONE_HOUR * 24; var defaultTimeArray = ["12:00 AM", "12:30 AM", "01:00 AM", "01:30 AM", "02:00 AM", "02:30 AM", "03:00 AM", "03:30 AM", "04:00 AM", "04:30 AM", "05:00 AM", "05:30 AM", "06:00 AM", "06:30 AM", "07:00 AM", "07:30 AM", "08:00 AM", "08:30 AM", "09:00 AM", "09:30 AM", "10:00 AM", "10:30 AM", "11:00 AM", "11:30 AM", "12:00 PM", "12:30 PM", "01:00 PM", "01:30 PM", "02:00 PM", "02:30 PM", "03:00 PM", "03:30 PM", "04:00 PM", "04:30 PM", "05:00 PM", "05:30 PM", "06:00 PM", "06:30 PM", "07:00 PM", "07:30 PM", "08:00 PM", "08:30 PM", "09:00 PM", "09:30 PM", "10:00 PM", "10:30 PM", "11:00 PM", "11:30 PM"]; function beforeShow(data) { sessionId = data.id; loadSessionData(); } function afterShow(data) { } function toggleDateTBD(e) { var status = $(e.target)[0].checked; var $dateField = $screen.find('#session-prop-start-date'); if (status) { $dateField.datepicker("disable"); } else { $dateField.datepicker("enable"); if ($dateField.val() == "") { $dateField.val(new Date().toDateString()); } toggleDate(); } } function events() { $startTimeList.on('change', toggleStartTime); $dateTimeTBD.on('ifChanged', toggleDateTBD); $screen.find("#session-update").on('click', updateSessionProperties); $inputFiles.on('change', changeSelectedFiles); $btnSelectFiles.on('click', toggleSelectFiles); } function toggleStartTime() { var valueSelected = $startTimeList.find('option:selected').val(); var startIndex = defaultTimeArray.indexOf(valueSelected) + 1; $endTimeList.empty(); // if (startIndex == defaultTimeArray.length ) { // var strTime = defaultTimeArray[0]; // $endTimeList.append($('')); // } var endIndex = startIndex + 6; var endTimeIndices = []; for (var i = startIndex; i < endIndex; i++) { if (i < defaultTimeArray.length) { endTimeIndices.push(i); } else { endTimeIndices.push(i - defaultTimeArray.length); } } $.each(endTimeIndices, function(index, value) { var strTime = defaultTimeArray[value]; $endTimeList.append($('')); }); $endTimeList.val(defaultTimeArray[(startIndex + 1) % defaultTimeArray.length]); context.JK.dropdown($endTimeList); } function getFormattedTime(date, change) { if (change) { date.setMinutes(Math.ceil(date.getMinutes() / 30) * 30); } var h12h = date.getHours(); var m12h = date.getMinutes(); var ampm; if (h12h >= 0 && h12h < 12) { if (h12h === 0) { h12h = 12; // 0 becomes 12 } ampm = "AM"; } else { if (h12h > 12) { h12h -= 12; // 13-23 becomes 1-11 } ampm = "PM"; } var timeString = ("00" + h12h).slice(-2) + ":" + ("00" + m12h).slice(-2) + " " + ampm; return timeString; } function toggleDate(startTime) { var selectedDate = null; if ($screen.find("#session-prop-start-date").val() == "") { selectedDate = new Date(); } else { selectedDate = new Date($screen.find('#session-prop-start-date').val()); } var currentDate = new Date(); var startIndex = 0; if (currentDate.getYear() == selectedDate.getYear() && currentDate.getMonth() == selectedDate.getMonth() && currentDate.getDate() == selectedDate.getDate()) { var timeString = getFormattedTime(currentDate, true); startIndex = defaultTimeArray.indexOf(timeString); if (startTime != null) { var curStartIndex = defaultTimeArray.indexOf(startTime); if (curStartIndex < startIndex) { startIndex = curStartIndex; } } } $startTimeList.empty(); for (var i = startIndex; i < defaultTimeArray.length; i++) { var strTime = defaultTimeArray[i]; $startTimeList.append($('')); } toggleStartTime(); context.JK.dropdown($startTimeList); context.JK.dropdown($endTimeList); } function validateForm() { var isValid = true; var name = $sessionName.val(); if (!name) { $screen.find('#divSessionName .error-text').remove(); $screen.find('#divSessionName').addClass("error"); $sessionName.after(""); isValid = false; } else { $screen.find('#divSessionName').removeClass("error"); } var description = $sessionDescription.val(); if (!description) { $screen.find('#divSessionDescription .error-text').remove(); $screen.find('#divSessionDescription').addClass("error"); $sessionDescription.after(""); isValid = false; } else { $screen.find('#divSessionDescription').removeClass("error"); } var genres = context.JK.GenreSelectorHelper.getSelectedGenres('#session-prop-genre'); if (genres.length === 0) { $screen.find('#divSessionGenre .error-text').remove(); $screen.find('#divSessionGenre').addClass("error"); $screen.find('#session-prop-genre').after(""); isValid = false; } else { $screen.find('#divSessionGenre').removeClass("error"); } return isValid; } function updateSessionProperties(e) { e.preventDefault(); if (validateForm() == false) return; var data = {}; data.name = $sessionName.val(); data.description = $sessionDescription.val(); data.genres = context.JK.GenreSelectorHelper.getSelectedGenres("#session-prop-genre"); if ($musicianAccess.val() == 'only-rsvp') { data.musician_access = false; data.approval_required = false; } else if ($musicianAccess.val() == 'musicians-approval') { data.musician_access = true; data.approval_required = true; } else if ($musicianAccess.val() == 'musicians') { data.musician_access = true; data.approval_required = false; } if ($fansAccess.val() == 'no-listen-chat') { data.fan_access = false; data.fan_chat = false; } else if ($fansAccess.val() == 'listen-chat-each') { data.fan_access = true; data.fan_chat = false; } else if ($fansAccess.val() == 'listen-chat-band') { data.fan_access = true; data.fan_chat = true; } data.legal_policy = $screen.find('#session-policy').val(); data.language = $languageList.val(); if ($dateTimeTBD[0].checked) { data.start = null; } else { data.start = $screen.find('#session-prop-start-date').val() + ' ' + $startTimeList.val(); var startIndex = defaultTimeArray.indexOf($startTimeList.val()); var endIndex = defaultTimeArray.indexOf($endTimeList.val()); if (endIndex > startIndex) { data.duration = (endIndex - startIndex) * 30; } else { data.duration = (endIndex + defaultTimeArray.length - startIndex + 1) * 30; } // var endDate = new Date($screen.find('#session-prop-start-date').val() + ' ' + $endTimeList.val()); // data.duration = (endDate - new Date(data.start)) / ONE_MINUTE; // if ($endTimeList.val() == defaultTimeArray[0]) { // data.duration += ONE_DAY / ONE_MINUTE; // } } data.recurring_mode = $recurringModeList.val(); data.music_notations = JSON.stringify(sessionData.music_notations); console.log("data.music_notations=%o", data.music_notations); data.timezone = $timezoneList.val(); data.open_rsvps = $screen.find("#open-rsvp")[0].checked; rest.updateScheduledSession(sessionData.id, data) .done(function(response) { loadSessionData(); app.notifyAlert("Session is successfully updated."); }) .fail(app.ajaxError); } function initializeControls() { $screen.find("#session-prop-start-date").datepicker({ dateFormat: "D d MM yy", onSelect: toggleDate } ); $screen.find(".icheckbuttons input").iCheck({ checkboxClass: 'icheckbox_minimal', radioClass: 'iradio_minimal', inheritClass: true }); context.JK.GenreSelectorHelper.render('#session-prop-genre'); context.JK.dropdown($musicianAccess); context.JK.dropdown($fansAccess); context.JK.dropdown($screen.find('#session-policy')); context.JK.dropdown($timezoneList); context.JK.dropdown($recurringModeList); context.JK.dropdown($languageList); } function loadSessionData() { rest.getSessionHistory(sessionId) .done(renderSession) .fail(app.ajaxError); } function getDiffIndex(duration) { if (!duration) { return 0; } else { var tokens = duration.split(':'); return parseInt(tokens[0]) * 2 + parseInt(tokens[1]) / 30; } } function uploadNotations(notations) { var formData = new FormData(); var maxExceeded = false; $.each(notations, function(i, file) { var max = 10 * 1024 * 1024; if(file.size > max) { maxExceeded = true; return false; } formData.append('files[]', file); }); if(maxExceeded) { app.notify( { title: "Maximum Music Notation Size Exceeded", text: "You can only upload files up to 10 megabytes in size." }); var deferred = new $.Deferred(); deferred.reject(); return deferred; } formData.append('client_id', app.clientId); //formData.append('session_id', sessionId); $btnSelectFiles.text('UPLOADING...').data('uploading', true) $uploadSpinner.show(); return rest.uploadMusicNotations(formData) .done(function(response) { var error_files = []; $.each(response, function(i, music_notation) { $actionBar.css("margin-top", parseInt($actionBar.css("margin-top")) + 20); if (music_notation.errors) { error_files.push(sessionData.music_notations[i].name); } }); if (error_files.length > 0) { app.notifyAlert("Failed to upload notations.", error_files.join(', ')); } sessionData.music_notations = $.merge(sessionData.music_notations, response); }) .fail(function(jqXHR) { if(jqXHR.status == 413) { // the file is too big. Let the user know. // This should happen when they select the file, but a misconfiguration on the server could cause this. app.notify( { title: "Maximum Music Notation Size Exceeded", text: "You can only upload files up to 10 megabytes in size." }) } else { app.notifyServerError(jqXHR, "Unable to upload music notations"); } }) .always(function() { $btnSelectFiles.text('SELECT FILES...').data('uploading', null) $uploadSpinner.hide(); }) } function changeSelectedFiles() { var fileNames = []; var files = $inputFiles.get(0).files; var error = false; for (var i = 0; i < files.length; ++i) { var name = files.item(i).name; var ext = name.split('.').pop().toLowerCase(); if ($.inArray(ext, ["pdf", "png", "jpg", "jpeg", "gif", "xml", "mxl", "txt"]) == -1) { error = true; break; } fileNames.push(name); } if (error) { app.notifyAlert("Error", "We're sorry, but you can only upload images (.png .jpg .jpeg .gif), text (.txt), PDFs (.pdf), and XML files (.xml .mxl)."); $inputFiles.replaceWith($inputFiles.clone(true)); } else { // upload as soon as user picks their files. uploadNotations($inputFiles.get(0).files) .done(function() { context._.each(fileNames, function(fileName) { var $text = $('').text(fileName); var $file = $('
  • ').append($text); $selectedFilenames.append($file); }) }) } } function toggleSelectFiles(event) { if($btnSelectFiles.data('uploading')) { logger.debug("ignoring click of SELECT FILES... while uploading"); return false; } event.preventDefault(); $inputFiles.trigger('click'); return false; } function renderSession(data) { sessionData = data; if (sessionData.scheduled_start == null) { $screen.find("#session-prop-start-date").datepicker("disable"); $dateTimeTBD.iCheck('check').attr('checked', true); } else { $screen.find('#session-prop-start-date').val(sessionData.scheduled_start_date); $dateTimeTBD.iCheck('uncheck').attr('checked', false); } var startTime = getFormattedTime(new Date(sessionData.scheduled_start), false); toggleDate(startTime); var diffIndex = getDiffIndex(sessionData.scheduled_duration); var endTime = defaultTimeArray[defaultTimeArray.indexOf(startTime) + diffIndex]; $startTimeList.val(startTime); toggleStartTime(); $endTimeList.val(endTime); if (sessionData.timezone == null) { context.JK.SessionUtils.defaultTimezone($timezoneList); } else { $timezoneList.val(sessionData.timezone); } $recurringModeList.val(sessionData.recurring_mode); context.JK.GenreSelectorHelper.setSelectedGenres('#session-prop-genre', sessionData.genres); $sessionName.val(sessionData.name); $sessionDescription.val(sessionData.description); $languageList.val(sessionData.language); if (sessionData.open_rsvps) { $screen.find("#open-rsvp").iCheck("check").attr("checked", true); } else { $screen.find("#open-rsvp").iCheck("uncheck").attr("checked", false); } sessionData.musician_access_value = 'musicians'; if (sessionData.musician_access == true && sessionData.approval_required == true) sessionData.musician_access_value = 'musicians-approval'; else if (sessionData.musician_access == false && sessionData.approval_required == false) sessionData.musician_access_value = 'only-rsvp'; sessionData.fans_access_value = 'listen-chat-each'; if (sessionData.fan_access == true && sessionData.fan_chat == true) sessionData.fans_access_value = 'listen-chat-band'; else if (sessionData.fan_access == false && sessionData.fan_chat == false) sessionData.fans_access_value = 'no-listen-chat'; $musicianAccess.val(sessionData.musician_access_value); $fansAccess.val(sessionData.fans_access_value); $screen.find('#session-policy').val(sessionData.legal_policy); $selectedFilenames.empty(); context._.each(sessionData.music_notations, function(notation) { var $link = notation.viewable ? $('').html(notation.file_name) : '#'; var $text = $('').html($link); var $file = $('
  • ').append($text); $musicNotations.append($file); }) } function initialize() { var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow }; app.bindScreen('account/sessionProperties', screenBindings); $propertiesBody = $screen.find("#account-session-properties-div"); $recurringModeList = $screen.find("#recurring-mode-prop-list"); $languageList = $screen.find("#session-prop-lang-list"); $timezoneList = $screen.find("#timezone-prop-list"); $startTimeList = $screen.find("#start-time-prop-list"); $endTimeList = $screen.find("#end-time-prop-list"); $sessionName = $screen.find("#session-prop-name"); $sessionDescription = $screen.find("#session-prop-desc"); $musicianAccess = $screen.find("#session-prop-musician-access"); $fansAccess = $screen.find("#session-prop-fans-access"); $musicNotations = $screen.find("#selected-filenames"); $btnSelectFiles = $screen.find(".btn-select-files"); $uploadSpinner = $screen.find(".upload-spinner"); $dateTimeTBD = $screen.find("#date_time_tbd"); $actionBar = $screen.find(".action-bar"); initializeControls(); events(); } this.initialize = initialize; this.beforeShow = beforeShow; this.afterShow = afterShow; return this; }; })(window, jQuery);