sintonia/airtime_mvc/public/js/airtime/library/spl.js

721 lines
17 KiB
JavaScript

//--------------------------------------------------------------------------------------------------------------------------------
// Playlist Functions
//--------------------------------------------------------------------------------------------------------------------------------
var AIRTIME = (function(AIRTIME){
AIRTIME.playlist = {};
var mod = AIRTIME.playlist;
function isTimeValid(time) {
var regExpr = new RegExp("^\\d{2}[:]\\d{2}[:]\\d{2}([.]\\d{1,6})?$");
return regExpr.test(time);
}
function isFadeValid(fade) {
var regExpr = new RegExp("^\\d{1}(\\d{1})?([.]\\d{1,6})?$");
return regExpr.test(fade);
}
function playlistError(json) {
alert(json.error);
openPlaylist(json);
}
function stopAudioPreview() {
// stop any preview playing
$('#jquery_jplayer_1').jPlayer('stop');
}
function highlightActive(el) {
$(el).addClass("ui-state-active");
}
function unHighlightActive(el) {
$(el).removeClass("ui-state-active");
}
function showError(el, error) {
$(el).parent().next()
.empty()
.append(error)
.show();
}
function hideError(el) {
$(el).parent().next()
.empty()
.hide();
}
function changeCueIn(event) {
event.stopPropagation();
var span = $(this),
id = span.parent().attr("id").split("_").pop(),
url = "/Playlist/set-cue",
cueIn = $.trim(span.text()),
li = span.parents("li"),
unqid = li.attr("unqid"),
lastMod = getModified();
if (!isTimeValid(cueIn)){
showError(span, "please put in a time '00:00:00 (.000000)'");
return;
}
$.post(url,
{format: "json", cueIn: cueIn, id: id, modified: lastMod},
function(json){
if (json.error !== undefined){
playlistError(json);
return;
}
if (json.cue_error !== undefined) {
showError(span, json.cue_error);
return;
}
setPlaylistContent(json);
li = $('#side_playlist li[unqid='+unqid+']');
li.find(".cue-edit").toggle();
highlightActive(li);
highlightActive(li.find('.spl_cue'));
});
}
function changeCueOut(event) {
event.stopPropagation();
var span = $(this),
id = span.parent().attr("id").split("_").pop(),
url = "/Playlist/set-cue",
cueOut = $.trim(span.text()),
li = span.parents("li"),
unqid = li.attr("unqid"),
lastMod = getModified();
if (!isTimeValid(cueOut)){
showError(span, "please put in a time '00:00:00 (.000000)'");
return;
}
$.post(url,
{format: "json", cueOut: cueOut, id: id, modified: lastMod},
function(json){
if (json.error !== undefined){
playlistError(json);
return;
}
if (json.cue_error !== undefined) {
showError(span, json.cue_error);
return;
}
setPlaylistContent(json);
li = $('#side_playlist li[unqid='+unqid+']');
li.find(".cue-edit").toggle();
highlightActive(li);
highlightActive(li.find('.spl_cue'));
});
}
function changeFadeIn(event) {
event.stopPropagation();
var span = $(this),
id = span.parent().attr("id").split("_").pop(),
url = "/Playlist/set-fade",
fadeIn = $.trim(span.text()),
li = span.parents("li"),
unqid = li.attr("unqid"),
lastMod = getModified();
if (!isFadeValid(fadeIn)){
showError(span, "please put in a time in seconds '00 (.000000)'");
return;
}
$.post(url,
{format: "json", fadeIn: fadeIn, id: id, modified: lastMod},
function(json){
if (json.error !== undefined){
playlistError(json);
return;
}
if (json.fade_error !== undefined) {
showError(span, json.fade_error);
return;
}
setPlaylistContent(json);
li = $('#side_playlist li[unqid='+unqid+']');
li.find('.crossfade').toggle();
highlightActive(li.find('.spl_fade_control'));
});
}
function changeFadeOut(event) {
event.stopPropagation();
var span = $(this),
id = span.parent().attr("id").split("_").pop(),
url = "/Playlist/set-fade",
fadeOut = $.trim(span.text()),
li = span.parents("li"),
unqid = li.attr("unqid"),
lastMod = getModified();
if (!isFadeValid(fadeOut)){
showError(span, "please put in a time in seconds '00 (.000000)'");
return;
}
$.post(url,
{format: "json", fadeOut: fadeOut, id: id, modified: lastMod},
function(json){
if (json.error !== undefined){
playlistError(json);
return;
}
if (json.fade_error !== undefined) {
showError(span, json.fade_error);
return;
}
setPlaylistContent(json);
li = $('#side_playlist li[unqid='+unqid+']');
li.find('.crossfade').toggle();
highlightActive(li.find('.spl_fade_control'));
});
}
function submitOnEnter(event) {
//enter was pressed
if(event.keyCode === 13) {
event.preventDefault();
$(this).blur();
}
}
function openFadeEditor(event) {
var pos, url, li;
event.stopPropagation();
li = $(this).parent().parent();
li.find(".crossfade").toggle();
if($(this).hasClass("ui-state-active")) {
unHighlightActive(this);
}
else {
highlightActive(this);
}
}
function openCueEditor(event) {
var pos, url, li, icon;
event.stopPropagation();
icon = $(this);
li = $(this).parent().parent().parent();
li.find(".cue-edit").toggle();
if (li.hasClass("ui-state-active")) {
unHighlightActive(li);
unHighlightActive(icon);
}
else {
highlightActive(li);
highlightActive(icon);
}
}
function editName() {
var nameElement = $(this),
playlistName = nameElement.text(),
lastMod = getModified();
$("#playlist_name_input")
.removeClass('element_hidden')
.val(playlistName)
.keydown(function(event){
if (event.keyCode === 13) {
event.preventDefault();
var input = $(this),
url = '/Playlist/set-playlist-name';
$.post(url,
{format: "json", name: input.val(), modified: lastMod},
function(json){
if (json.error !== undefined) {
playlistError(json);
}
else {
setModified(json.modified);
input.addClass('element_hidden');
nameElement.text(json.playlistName);
redrawLib();
}
});
}
})
.focus();
}
function redrawLib() {
var dt = $("#library_display").dataTable(),
oLibTT = TableTools.fnGetInstance('library_display');
oLibTT.fnSelectNone();
dt.fnStandingRedraw();
}
function setPlaylistContent(json) {
$('#spl_name > a')
.empty()
.append(json.name);
$('#spl_length')
.empty()
.append(json.length);
$('#fieldset-metadate_change textarea')
.empty()
.val(json.description);
$('#spl_sortable')
.empty()
.append(json.html);
setModified(json.modified);
redrawLib();
}
function getId() {
return parseInt($("#pl_id").val(), 10);
}
function getModified() {
return parseInt($("#pl_lastMod").val(), 10);
}
function setModified(modified) {
$("#pl_lastMod").val(modified);
}
function openPlaylist(json) {
$("#side_playlist")
.empty()
.append(json.html);
setUpPlaylist();
}
//sets events dynamically for playlist entries (each row in the playlist)
function setPlaylistEntryEvents(el) {
$(el).delegate("#spl_sortable .ui-icon-closethick",
{"click": function(ev){
var id;
id = parseInt($(this).attr("id").split("_").pop(), 10);
AIRTIME.playlist.fnDeleteItems([id]);
}});
$(el).delegate(".spl_fade_control",
{"click": openFadeEditor});
$(el).delegate(".spl_cue",
{"click": openCueEditor});
//add the play function to the play icon
$(el).delegate(".big_play",
{"click": openAudioPreview});
}
//sets events dynamically for the cue editor.
function setCueEvents(el) {
$(el).delegate(".spl_cue_in span",
{"focusout": changeCueIn,
"keydown": submitOnEnter});
$(el).delegate(".spl_cue_out span",
{"focusout": changeCueOut,
"keydown": submitOnEnter});
}
//sets events dynamically for the fade editor.
function setFadeEvents(el) {
$(el).delegate(".spl_fade_in span",
{"focusout": changeFadeIn,
"keydown": submitOnEnter});
$(el).delegate(".spl_fade_out span",
{"focusout": changeFadeOut,
"keydown": submitOnEnter});
}
function setUpPlaylist(playlist) {
var playlist = $("#side_playlist"),
sortableConf,
cachedDescription;
playlist.find("#spl_crossfade").on("click", function() {
var lastMod = getModified();
if ($(this).hasClass("ui-state-active")) {
$(this).removeClass("ui-state-active");
playlist.find("#crossfade_main").hide();
}
else {
$(this).addClass("ui-state-active");
var url = '/Playlist/get-playlist-fades';
$.get(url,
{format: "json", modified: lastMod},
function(json){
if (json.error !== undefined){
playlistError(json);
}
else {
playlist.find("#spl_fade_in_main").find("span")
.empty()
.append(json.fadeIn);
playlist.find("#spl_fade_out_main").find("span")
.empty()
.append(json.fadeOut);
playlist.find("#crossfade_main").show();
}
});
}
});
playlist.find("#playlist_name_display").on("click", editName);
playlist.find("#fieldset-metadate_change > legend").on("click", function(){
var descriptionElement = $(this).parent();
if (descriptionElement.hasClass("closed")) {
cachedDescription = playlist.find("#fieldset-metadate_change textarea").val();
descriptionElement.removeClass("closed");
}
else {
descriptionElement.addClass("closed");
}
});
playlist.find("#description_save").on("click", function(){
var textarea = playlist.find("#fieldset-metadate_change textarea"),
description = textarea.val(),
url,
lastMod = getModified();;
url = '/Playlist/set-playlist-description';
$.post(url,
{format: "json", description: description, modified: lastMod},
function(json){
if (json.error !== undefined){
playlistError(json);
}
else{
setModified(json.modified);
textarea.val(json.description);
playlist.find("#fieldset-metadate_change").addClass("closed");
redrawLib();
}
});
});
playlist.find("#description_cancel").on("click", function(){
var textarea = playlist.find("#fieldset-metadate_change textarea");
textarea.val(cachedDescription);
playlist.find("#fieldset-metadate_change").addClass("closed");
});
playlist.find("#spl_fade_in_main span:first").on("blur", function(event){
event.stopPropagation();
var url = "/Playlist/set-playlist-fades",
span = $(this),
fadeIn = $.trim(span.text()),
lastMod = getModified();
if (!isFadeValid(fadeIn)){
showError(span, "please put in a time in seconds '00 (.000000)'");
return;
}
$.post(url,
{format: "json", fadeIn: fadeIn, modified: lastMod},
function(json){
hideError(span);
});
});
playlist.find("#spl_fade_out_main span:last").on("blur", function(event){
event.stopPropagation();
var url = "/Playlist/set-playlist-fades",
span = $(this),
fadeOut = $.trim(span.text()),
lastMod = getModified();
if(!isFadeValid(fadeOut)){
showError(span, "please put in a time in seconds '00 (.000000)'");
return;
}
$.post(url,
{format: "json", fadeOut: fadeOut, modified: lastMod},
function(json){
hideError(span);
});
});
playlist.find("#spl_fade_in_main span:first, #spl_fade_out_main span:first")
.on("keydown", submitOnEnter);
playlist.find("#crossfade_main > .ui-icon-closethick").on("click", function(){
playlist.find("#spl_crossfade").removeClass("ui-state-active");
playlist.find("#crossfade_main").hide();
});
sortableConf = (function(){
var aReceiveItems,
html,
fnReceive,
fnUpdate;
fnReceive = function(event, ui) {
var aItems = [],
aSelected,
oLibTT = TableTools.fnGetInstance('library_display'),
i,
length;
//filter out anything that isn't an audiofile.
aSelected = oLibTT.fnGetSelectedData();
//if nothing is checked select the dragged item.
if (aSelected.length === 0) {
aSelected.push(ui.item.data("aData"));
}
for (i = 0, length = aSelected.length; i < length; i++) {
if (aSelected[i].ftype === "audioclip") {
aItems.push(aSelected[i].id);
}
}
aReceiveItems = aItems;
html = ui.helper.html();
};
fnUpdate = function(event, ui) {
var prev,
aItems = [],
iAfter,
sAddType;
prev = ui.item.prev();
if (prev.hasClass("spl_empty") || prev.length === 0) {
iAfter = undefined;
sAddType = 'before';
}
else {
iAfter = parseInt(prev.attr("id").split("_").pop(), 10);
sAddType = 'after';
}
//item was dragged in from library datatable
if (aReceiveItems !== undefined) {
playlist.find("tr.ui-draggable")
.after(html)
.empty();
aItems = aReceiveItems;
aReceiveItems = undefined;
AIRTIME.playlist.fnAddItems(aItems, iAfter, sAddType);
}
//item was reordered.
else {
aItems.push(parseInt(ui.item.attr("id").split("_").pop(), 10));
AIRTIME.playlist.fnMoveItems(aItems, iAfter);
}
};
return {
items: 'li',
//hack taken from
//http://stackoverflow.com/questions/2150002/jquery-ui-sortable-how-can-i-change-the-appearance-of-the-placeholder-object
placeholder: {
element: function(currentItem) {
return $('<li class="placeholder ui-state-highlight"></li>')[0];
},
update: function(container, p) {
return;
}
},
forcePlaceholderSize: true,
handle: 'div.list-item-container',
start: function(event, ui) {
ui.placeholder.height(56);
},
receive: fnReceive,
update: fnUpdate
};
}());
playlist.find("#spl_sortable").sortable(sortableConf);
}
mod.fnNew = function() {
var url = '/Playlist/new';
stopAudioPreview();
$.post(url,
{format: "json"},
function(json){
openPlaylist(json);
redrawLib();
});
};
mod.fnEdit = function(id) {
var url = '/Playlist/edit';;
stopAudioPreview();
$.post(url,
{format: "json", id: id},
function(json){
openPlaylist(json);
});
};
mod.fnDelete = function(plid) {
var url, id, lastMod;
stopAudioPreview();
id = (plid === undefined) ? getId() : plid;
lastMod = getModified();
url = '/Playlist/delete';
$.post(url,
{format: "json", ids: id, modified: lastMod},
function(json){
openPlaylist(json);
redrawLib();
});
};
mod.fnAddItems = function(aItems, iAfter, sAddType) {
var lastMod = getModified();
$.post("/playlist/add-items",
{format: "json", "ids": aItems, "afterItem": iAfter, "type": sAddType, "modified": lastMod},
function(json){
if (json.error !== undefined) {
playlistError(json);
}
else {
setPlaylistContent(json);
}
});
};
mod.fnMoveItems = function(aIds, iAfter) {
var lastMod = getModified();
$.post("/playlist/move-items",
{format: "json", "ids": aIds, "afterItem": iAfter, "modified": lastMod},
function(json){
if (json.error !== undefined) {
playlistError(json);
}
else {
setPlaylistContent(json);
}
});
};
mod.fnDeleteItems = function(aItems) {
var lastMod = getModified();
$.post("/playlist/delete-items",
{format: "json", "ids": aItems, "modified": lastMod},
function(json){
if (json.error !== undefined) {
playlistError(json);
}
else {
setPlaylistContent(json);
}
});
};
mod.init = function() {
var playlist = $("#side_playlist");
$(playlist).delegate("#spl_new",
{"click": AIRTIME.playlist.fnNew});
$(playlist).delegate("#spl_delete", {"click": function(ev){
AIRTIME.playlist.fnDelete();
}});
setPlaylistEntryEvents(playlist);
setCueEvents(playlist);
setFadeEvents(playlist);
setUpPlaylist(playlist);
};
return AIRTIME;
}(AIRTIME || {}));
$(document).ready(function() {
var viewport = AIRTIME.utilities.findViewportDimensions(),
lib = $("#library_content"),
pl = $("#side_playlist"),
widgetHeight = viewport.height - 185,
width = Math.floor(viewport.width - 110);
lib.height(widgetHeight)
.width(Math.floor(width * 0.55));
pl.height(widgetHeight)
.width(Math.floor(width * 0.45));
AIRTIME.library.libraryInit();
AIRTIME.playlist.init();
});