sintonia/legacy/public/js/airtime/common/common.js

414 lines
10 KiB
JavaScript

var previewWidth = 482,
previewHeight = 110;
$(document).ready(function () {
/* Removed as this is now (hopefully) unnecessary */
//$("#Panel").stickyPanel({
// topPadding: 1,
// afterDetachCSSClass: "floated-panel",
// savePanelSpace: true
//});
//this statement tells the browser to fade out any success message after 5 seconds
setTimeout(function () {
$(".success").fadeOut("slow");
}, 5000);
});
/*
* i18n_months and i18n_days_short are used in jquery datepickers
* which we use in multiple places
*/
var i18n_months = [
$.i18n._("January"),
$.i18n._("February"),
$.i18n._("March"),
$.i18n._("April"),
$.i18n._("May"),
$.i18n._("June"),
$.i18n._("July"),
$.i18n._("August"),
$.i18n._("September"),
$.i18n._("October"),
$.i18n._("November"),
$.i18n._("December"),
];
var i18n_months_short = [
$.i18n._("Jan"),
$.i18n._("Feb"),
$.i18n._("Mar"),
$.i18n._("Apr"),
$.i18n._("May"),
$.i18n._("Jun"),
$.i18n._("Jul"),
$.i18n._("Aug"),
$.i18n._("Sep"),
$.i18n._("Oct"),
$.i18n._("Nov"),
$.i18n._("Dec"),
];
var i18n_days_short = [
$.i18n._("Su"),
$.i18n._("Mo"),
$.i18n._("Tu"),
$.i18n._("We"),
$.i18n._("Th"),
$.i18n._("Fr"),
$.i18n._("Sa"),
];
var HTTPMethods = Object.freeze({
GET: "GET",
POST: "POST",
PUT: "PUT",
PATCH: "PATCH",
DELETE: "DELETE",
OPTIONS: "OPTIONS",
});
var dateStartId = "#sb_date_start",
timeStartId = "#sb_time_start",
dateEndId = "#sb_date_end",
timeEndId = "#sb_time_end";
function getDatatablesStrings(overrideDict) {
var dict = {
sEmptyTable: $.i18n._("No data available in table"),
sInfo: $.i18n._("Showing _START_ to _END_ of _TOTAL_ entries"),
sInfoEmpty: $.i18n._("Showing 0 to 0 of 0 entries"),
sInfoFiltered: "", // $.i18n._("(filtered from _MAX_ total entries)"),
sInfoPostFix: $.i18n._(""),
sInfoThousands: $.i18n._(","),
sLengthMenu: $.i18n._("Show _MENU_"),
sLoadingRecords: $.i18n._("Loading..."),
//"sProcessing": $.i18n._("Processing..."),
sProcessing: $.i18n._(""),
sSearch: $.i18n._(""),
sZeroRecords: $.i18n._("No matching records found"),
oPaginate: {
sFirst: "«",
sLast: "»",
sNext: "›",
sPrevious: "‹",
},
//"oPaginate": {
// "sFirst": $.i18n._("First"),
// "sLast": $.i18n._("Last"),
// "sNext": $.i18n._("Next"),
// "sPrevious": $.i18n._("Previous")
//},
oAria: {
sSortAscending: $.i18n._(": activate to sort column ascending"),
sSortDescending: $.i18n._(": activate to sort column descending"),
},
};
return $.extend({}, dict, overrideDict);
}
function adjustDateToServerDate(date, serverTimezoneOffset) {
//date object stores time in the browser's localtime. We need to artificially shift
//it to
var timezoneOffset = date.getTimezoneOffset() * 60 * 1000;
date.setTime(date.getTime() + timezoneOffset + serverTimezoneOffset * 1000);
/* date object has been shifted to artificial UTC time. Now let's
* shift it to the server's timezone */
return date;
}
/**
*handle to the jplayer window
*/
var _preview_window = null;
/**
*Gets the info from the view when menu action play choosen and opens the jplayer window.
*/
function openAudioPreview(p_event) {
p_event.stopPropagation();
var audioFileID = $(this).attr("audioFile");
var objId = $(".obj_id:first").attr("value");
var objType = $(".obj_type:first").attr("value");
var playIndex = $(this).parent().parent().attr("id");
playIndex = playIndex.substring(4); //remove the spl_
if (objType == "playlist") {
open_playlist_preview(objId, playIndex);
} else if (objType == "block") {
open_block_preview(objId, playIndex);
}
}
function open_audio_preview(type, id) {
// The reason that we need to encode artist and title string is that
// sometime they contain '/' or '\' and apache reject %2f or %5f
// so the work around is to encode it twice.
openPreviewWindow(
baseUrl + "audiopreview/audio-preview/audioFileID/" + id + "/type/" + type,
previewWidth,
previewHeight,
);
_preview_window.focus();
}
/**
*Opens a jPlayer window for the specified info, for either an audio file or playlist.
*If audioFile, audioFileTitle, audioFileArtist is supplied the jplayer opens for one file
*Otherwise the playlistID and playlistIndex was supplied and a playlist is played starting with the
*given index.
*/
function open_playlist_preview(p_playlistID, p_playlistIndex) {
if (p_playlistIndex == undefined)
//Use a resonable default.
p_playlistIndex = 0;
if (_preview_window != null && !_preview_window.closed)
_preview_window.playAllPlaylist(p_playlistID, p_playlistIndex);
else
openPreviewWindow(
baseUrl +
"audiopreview/playlist-preview/playlistIndex/" +
p_playlistIndex +
"/playlistID/" +
p_playlistID,
previewWidth,
previewHeight,
);
_preview_window.focus();
}
function open_block_preview(p_blockId, p_blockIndex) {
if (p_blockIndex == undefined)
//Use a resonable default.
p_blockIndex = 0;
if (_preview_window != null && !_preview_window.closed)
_preview_window.playBlock(p_blockId, p_blockIndex);
else
openPreviewWindow(
baseUrl +
"audiopreview/block-preview/blockIndex/" +
p_blockIndex +
"/blockId/" +
p_blockId,
previewWidth,
previewHeight,
);
_preview_window.focus();
}
/**
*Opens a jPlayer window for the specified info, for either an audio file or playlist.
*If audioFile, audioFileTitle, audioFileArtist is supplied the jplayer opens for one file
*Otherwise the playlistID and playlistIndex was supplied and a playlist is played starting with the
*given index.
*/
function open_show_preview(p_showID, p_showIndex) {
if (_preview_window != null && !_preview_window.closed)
_preview_window.playAllShow(p_showID, p_showIndex);
else
openPreviewWindow(
baseUrl +
"audiopreview/show-preview/showID/" +
p_showID +
"/showIndex/" +
p_showIndex,
previewWidth,
previewHeight,
);
_preview_window.focus();
}
function openPreviewWindow(url, w, h) {
var dim = w && h ? "width=" + w + ",height=" + h + "," : "";
// Hardcoding this here is kinda gross, but the alternatives aren't much better...
_preview_window = window.open(
url,
$.i18n._("Audio Player"),
dim + "scrollbars=yes",
);
return false;
}
function validateTimeRange() {
var oRange,
inputs = $(".sb-timerange > input"),
start,
end;
oRange = AIRTIME.utilities.fnGetScheduleRange(
dateStartId,
timeStartId,
dateEndId,
timeEndId,
);
start = oRange.start;
end = oRange.end;
if (end >= start) {
inputs.removeClass("error");
} else {
if (!inputs.hasClass("error")) {
inputs.addClass("error");
}
}
return {
start: start,
end: end,
isValid: end >= start,
};
}
// validate uploaded images
function validateImage(img, el) {
// remove any existing error messages
if ($("#img-err")) {
$("#img-err").remove();
}
if (img.size > 2048000) {
// 2MB - pull this from somewhere instead?
// hack way of inserting an error message
var err = $.i18n._("Selected file is too large");
el.parent().after(
"<ul id='img-err' class='errors'>" + "<li>" + err + "</li>" + "</ul>",
);
return false;
} else if (validateMimeType(img.type) < 0) {
var err = $.i18n._("File format is not supported");
el.parent().after(
"<ul id='img-err' class='errors'>" + "<li>" + err + "</li>" + "</ul>",
);
return false;
}
return true;
}
// validate image mime type
function validateMimeType(mime) {
var extensions = [
"image/jpeg",
"image/png",
"image/gif",
// BMP?
];
return $.inArray(mime, extensions);
}
function pad(number, length) {
return sprintf("%'0" + length + "d", number);
}
function removeSuccessMsg() {
var $status = $(".success");
$status.fadeOut("slow", function () {
$status.empty();
});
}
function hideHint(h) {
h.hide("slow").addClass("hidden");
}
function showHint(h) {
h.show("slow").removeClass("hidden");
}
function getUsabilityHint() {
var pathname = window.location.pathname;
$.getJSON(
baseUrl + "api/get-usability-hint",
{ format: "json", userPath: pathname },
function (json) {
var $hint_div = $(".usability_hint");
var current_hint = $hint_div.html();
if (json === "") {
// there are no more hints to display to the user
hideHint($hint_div);
} else if (current_hint !== json) {
// we only change the message if it is new
if ($hint_div.is(":visible")) {
hideHint($hint_div);
}
$hint_div.html(json);
showHint($hint_div);
} else {
// hint is the same before we hid it so we just need to show it
if ($hint_div.is(":hidden")) {
showHint($hint_div);
}
}
},
);
}
// TODO: build this out so we can use it as a fallback in fail cases
function buildErrorDialog(message) {
var el = $("<div id='error_dialog'></div>");
el.text(message);
$(document.body).append(el);
$("#error_dialog").dialog({
title: $.i18n._("Something went wrong!"),
resizable: false,
modal: true,
width: "auto",
height: "auto",
});
}
/**
* Add title attributes (whose values are their inner text) to all elements in the calling parent matching selector
*
* @param selector jQuery selector to search descendants
* @returns {jQuery}
*/
jQuery.fn.addTitles = function (selector) {
this.each(function () {
// Put this in a mouseenter event handler so it's dynamic
// (newly created elements will have the title applied on hover)
$(this).on("mouseenter", selector, function () {
$(this).attr("title", $(this).text());
});
});
return this; // jQuery chaining
};
// XXX: Old code to pan selector text; keeping this around in case we want to use it later - Duncan
jQuery.fn.scrollText = function (selector) {
this.each(function () {
$(this).on("mouseenter", selector, function () {
var sw = $(this)[0].scrollWidth - parseFloat($(this).css("textIndent")),
iw = $(this).innerWidth();
if (sw > iw) {
$(this)
.stop()
.animate(
{
textIndent: "-" + (sw + 1 - iw) + "px",
},
sw * 8,
);
}
});
$(this).on("mouseleave", selector, function () {
$(this).stop().animate(
{
textIndent: "0",
},
500,
);
});
});
return this;
};