SAAS-948 - ShowBuilder redesign initial commit
This commit is contained in:
parent
d9117721b9
commit
d7d9a994d5
|
@ -130,9 +130,9 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
protected function _initTasks() {
|
||||
/* We need to wrap this here so that we aren't checking when we're running the unit test suite
|
||||
*/
|
||||
$taskManager = TaskManager::getInstance();
|
||||
$taskManager->runTask(AirtimeTask::UPGRADE); // Run the upgrade on each request (if it needs to be run)
|
||||
if (getenv("AIRTIME_UNIT_TEST") != 1) {
|
||||
$taskManager = TaskManager::getInstance();
|
||||
$taskManager->runTask(AirtimeTask::UPGRADE); // Run the upgrade on each request (if it needs to be run)
|
||||
//This will do the upgrade too if it's needed...
|
||||
$taskManager->runTasks();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
|
|||
->add(new Zend_Acl_Resource('dashboard'))
|
||||
->add(new Zend_Acl_Resource('preference'))
|
||||
->add(new Zend_Acl_Resource('showbuilder'))
|
||||
->add(new Zend_Acl_Resource('show-builder'))
|
||||
->add(new Zend_Acl_Resource('playouthistory'))
|
||||
->add(new Zend_Acl_Resource('playouthistorytemplate'))
|
||||
->add(new Zend_Acl_Resource('listenerstat'))
|
||||
|
@ -49,6 +50,7 @@ $ccAcl->allow('G', 'index')
|
|||
->allow('G', 'error')
|
||||
->allow('G', 'user', 'edit-user')
|
||||
->allow('G', 'showbuilder')
|
||||
->allow('G', 'show-builder')
|
||||
->allow('G', 'api')
|
||||
->allow('G', 'schedule')
|
||||
->allow('G', 'dashboard')
|
||||
|
|
|
@ -11,6 +11,7 @@ class LibraryController extends Zend_Controller_Action
|
|||
{
|
||||
$ajaxContext = $this->_helper->getHelper('AjaxContext');
|
||||
$ajaxContext->addActionContext('contents-feed', 'json')
|
||||
->addActionContext('contents-feed-test', 'json')
|
||||
->addActionContext('delete', 'json')
|
||||
->addActionContext('duplicate', 'json')
|
||||
->addActionContext('delete-group', 'json')
|
||||
|
@ -425,6 +426,19 @@ class LibraryController extends Zend_Controller_Action
|
|||
$this->view->files = SecurityHelper::htmlescape_recursive($r["aaData"]);
|
||||
}
|
||||
|
||||
public function contentsFeedTestAction()
|
||||
{
|
||||
$params = $this->getRequest()->getParams();
|
||||
|
||||
# terrible name for the method below. it does not only search files.
|
||||
$r = Application_Model_StoredFile::searchLibraryFiles($params);
|
||||
|
||||
$this->view->sEcho = $r["sEcho"];
|
||||
$this->view->iTotalDisplayRecords = $r["iTotalDisplayRecords"];
|
||||
$this->view->iTotalRecords = $r["iTotalRecords"];
|
||||
$this->view->files = SecurityHelper::htmlescape_recursive($r["aaData"]);
|
||||
}
|
||||
|
||||
public function editFileMdAction()
|
||||
{
|
||||
$user = Application_Model_User::getCurrentUser();
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
class ShowBuilderController extends Zend_Controller_Action {
|
||||
|
||||
public function init() {
|
||||
}
|
||||
|
||||
public function indexAction() {
|
||||
$CC_CONFIG = Config::getConfig();
|
||||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
$userType = Application_Model_User::GetCurrentUser()->getType();
|
||||
|
||||
$this->view->headScript()->appendScript("localStorage.setItem( 'user-type', '$userType' );");
|
||||
$this->view->headScript()->appendScript(Application_Common_GoogleAnalytics::generateGoogleTagManagerDataLayerJavaScript());
|
||||
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/contextmenu/jquery.contextMenu.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/js/jquery.dataTables.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.pluginAPI.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.fnSetFilteringDelay.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.ColVis.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.FixedColumns.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/datatables/plugin/dataTables.columnFilter.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/blockui/jquery.blockUI.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/buttons/buttons.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/utilities/utilities.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/media_library.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.contextMenu.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColReorder.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/library/library-test.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/library/events/library_showbuilder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
// PLUPLOAD
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/libs/dropzone.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/dropzone/dropzone.min.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/builder_test.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/main_builder_test.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.ui.timepicker.css?'.$CC_CONFIG['airtime_version']);
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/showbuilder.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
$csrf_namespace = new Zend_Session_Namespace('csrf_namespace');
|
||||
$csrf_element = new Zend_Form_Element_Hidden('csrf');
|
||||
$csrf_element->setValue($csrf_namespace->authtoken)->setRequired('true')->removeDecorator('HtmlTag')->removeDecorator('Label');
|
||||
$this->view->csrf = $csrf_element;
|
||||
}
|
||||
|
||||
}
|
|
@ -907,6 +907,112 @@ SQL;
|
|||
return $results;
|
||||
}
|
||||
|
||||
public static function searchLibraryFilesTest($datatables)
|
||||
{
|
||||
$con = Propel::getConnection(CcFilesPeer::DATABASE_NAME);
|
||||
$displayColumns = self::getLibraryColumns();
|
||||
|
||||
$fileSelect = array();
|
||||
foreach ($displayColumns as $key) {
|
||||
if ($key === "id") {
|
||||
$fileSelect[] = "FILES.id AS $key";
|
||||
} elseif ($key === "owner_id") {
|
||||
$fileSelect[] = "sub.login AS $key";
|
||||
} //file length is displayed based on cueout - cuein.
|
||||
else if ($key === "length") {
|
||||
$fileSelect[] = "(cueout - cuein)::INTERVAL AS length";
|
||||
} elseif ($key === "year") {
|
||||
$fileSelect[] = "year AS ".$key;
|
||||
} else {
|
||||
$fileSelect[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
$fileSelect = "SELECT ". join(",", $fileSelect);
|
||||
$fileTable = "({$fileSelect} FROM cc_files AS FILES LEFT JOIN cc_subjs AS sub ON (sub.id = FILES.owner_id) WHERE file_exists = 'TRUE' AND hidden='FALSE')";
|
||||
$fromTable = $fileTable." AS File"; //need an alias for the table if it's standalone.
|
||||
|
||||
// update is_scheduled to false for tracks that
|
||||
// have already played out
|
||||
self::updatePastFilesIsScheduled();
|
||||
$results = Application_Model_Datatables::findEntries($con, $displayColumns, $fromTable, $datatables);
|
||||
|
||||
$displayTimezone = new DateTimeZone(Application_Model_Preference::GetUserTimezone());
|
||||
$utcTimezone = new DateTimeZone("UTC");
|
||||
|
||||
foreach ($results['aaData'] as &$row) {
|
||||
$row['id'] = intval($row['id']);
|
||||
|
||||
//taken from Datatables.php, needs to be cleaned up there.
|
||||
if (isset($r['ftype'])) {
|
||||
if ($r['ftype'] == 'playlist') {
|
||||
$pl = new Application_Model_Playlist($r['id']);
|
||||
$r['length'] = $pl->getLength();
|
||||
} elseif ($r['ftype'] == "block") {
|
||||
$bl = new Application_Model_Block($r['id']);
|
||||
$r['bl_type'] = $bl->isStatic() ? 'static' : 'dynamic';
|
||||
$r['length'] = $bl->getLength();
|
||||
}
|
||||
}
|
||||
|
||||
if ($row['ftype'] === "audioclip") {
|
||||
|
||||
$cuein_formatter = new LengthFormatter($row["cuein"]);
|
||||
$row["cuein"] = $cuein_formatter->format();
|
||||
|
||||
$cueout_formatter = new LengthFormatter($row["cueout"]);
|
||||
$row["cueout"] = $cueout_formatter->format();
|
||||
|
||||
$cuein = Application_Common_DateHelper::playlistTimeToSeconds($row["cuein"]);
|
||||
$cueout = Application_Common_DateHelper::playlistTimeToSeconds($row["cueout"]);
|
||||
$row_length = Application_Common_DateHelper::secondsToPlaylistTime($cueout - $cuein);
|
||||
|
||||
$formatter = new SamplerateFormatter($row['sample_rate']);
|
||||
$row['sample_rate'] = $formatter->format();
|
||||
|
||||
$formatter = new BitrateFormatter($row['bit_rate']);
|
||||
$row['bit_rate'] = $formatter->format();
|
||||
|
||||
// for audio preview
|
||||
$row['audioFile'] = $row['id'].".".pathinfo($row['filepath'], PATHINFO_EXTENSION);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
$row['audioFile'] = $row['id'];
|
||||
$row_length = $row['length'];
|
||||
}
|
||||
|
||||
$len_formatter = new LengthFormatter($row_length);
|
||||
$row['length'] = $len_formatter->format();
|
||||
|
||||
//convert mtime and utime to localtime
|
||||
$row['mtime'] = new DateTime($row['mtime'], $utcTimezone);
|
||||
$row['mtime']->setTimeZone($displayTimezone);
|
||||
$row['mtime'] = $row['mtime']->format(DEFAULT_TIMESTAMP_FORMAT);
|
||||
$row['utime'] = new DateTime($row['utime'], $utcTimezone);
|
||||
$row['utime']->setTimeZone($displayTimezone);
|
||||
$row['utime'] = $row['utime']->format(DEFAULT_TIMESTAMP_FORMAT);
|
||||
|
||||
//need to convert last played to localtime if it exists.
|
||||
if (isset($row['lptime'])) {
|
||||
$row['lptime'] = new DateTime($row['lptime'], $utcTimezone);
|
||||
$row['lptime']->setTimeZone($displayTimezone);
|
||||
$row['lptime'] = $row['lptime']->format(DEFAULT_TIMESTAMP_FORMAT);
|
||||
}
|
||||
|
||||
// we need to initalize the checkbox and image row because we do not retrieve
|
||||
// any data from the db for these and datatables will complain
|
||||
$row['checkbox'] = "";
|
||||
$row['image'] = "";
|
||||
|
||||
$type = substr($row['ftype'], 0, 2);
|
||||
$row['tr_id'] = "{$type}_{$row['id']}";
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a newly uploaded audio file from its temporary upload directory
|
||||
* on the local disk (like /tmp) over to Airtime's "stor" directory,
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<style>
|
||||
body {
|
||||
background: #242424;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
position: absolute;
|
||||
background: #242424;
|
||||
top: 138px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
/*padding: 0;*/
|
||||
padding: 2em;
|
||||
}
|
||||
</style>
|
||||
<form action="/rest/media" method="post" id="upload_form" class="dropzone dz-clickable" <?php if ($this->quotaLimitReached) { ?> class="hidden" <?php } ?>>
|
||||
<?php echo $this->csrf ?>
|
||||
<div class="dz-message">
|
||||
<?php echo _("Drop files here or click to upload") ?>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="media_type_nav">
|
||||
<button id="new_media_selector" class="btn btn-small dropdown-toggle" data-toggle="dropdown">
|
||||
New <span class="caret"></span>
|
||||
</button>
|
||||
<div class="media_type_selector selected" selection_id="1">Files</div>
|
||||
<div class="media_type_selector" selection_id="2">Playlists</div>
|
||||
<div class="media_type_selector" selection_id="3">Smart Blocks</div>
|
||||
<div class="media_type_selector" selection_id="4">Webstreams</div>
|
||||
</div>
|
||||
|
||||
<div id="library_content" class="lib-content tabs lib-test">
|
||||
<?php echo $this->render('widgets/lib-table.phtml') ?>
|
||||
</div>
|
||||
|
||||
<div id="show_builder" class="sb-content sb-test">
|
||||
<div class="sb-timerange">
|
||||
<?php echo $this->sb_form; ?>
|
||||
</div>
|
||||
<table id="show_builder_table" cellpadding="0" cellspacing="0" class="datatable"></table>
|
||||
</div>
|
||||
<?php echo $this->dialog ?>
|
|
@ -0,0 +1,10 @@
|
|||
<fieldset class="toggle closed" id="filter_options">
|
||||
<legend style="cursor: pointer;">
|
||||
<span class="ui-icon ui-icon-triangle-2-n-s"></span>
|
||||
<?php echo _("Advanced Search Options") ?>
|
||||
</legend>
|
||||
<div id="advanced_search" class="advanced_search form-horizontal"></div>
|
||||
</fieldset>
|
||||
|
||||
<table id="library_display" cellpadding="0" cellspacing="0" class="datatable">
|
||||
</table>
|
|
@ -378,7 +378,6 @@ INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s4_channels', 'ste
|
|||
|
||||
-- added in 2.5.14 - this can't be set up in Propel's XML schema, so we need to do it here -- Duncan
|
||||
|
||||
ALTER TABLE cc_pref ALTER COLUMN subjid SET NULL;
|
||||
ALTER TABLE cc_pref ALTER COLUMN subjid SET DEFAULT NULL;
|
||||
CREATE UNIQUE INDEX cc_pref_key_idx ON cc_pref (keystr) WHERE subjid IS NULL;
|
||||
ANALYZE cc_pref; -- this validates the new partial index
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -37,7 +37,6 @@
|
|||
|
||||
#library_content {
|
||||
float: left;
|
||||
width: 50%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
|
|
@ -180,8 +180,8 @@ table.datatable tr.cursor-selected-row td, table.datatable tr.cursor-selected-ro
|
|||
background-color: rgba(255, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.sb-now-playing td {
|
||||
background-color: rgba(23, 235, 37, 1) !important;
|
||||
.sb-now-playing {
|
||||
background-color: rgba(23, 235, 37, 1);
|
||||
}
|
||||
|
||||
.sb-content.padded {
|
||||
|
|
|
@ -830,9 +830,9 @@ dl.inline-list dd {
|
|||
.datatable tr.odd.selected td {
|
||||
background-color: #c5deeb;
|
||||
}
|
||||
.datatable tr.odd:hover td, .datatable tr.even:hover td {
|
||||
background-color: #95d5f7 !important;
|
||||
}
|
||||
/*.datatable tr.odd:hover td, .datatable tr.even:hover td {*/
|
||||
/*background-color: #95d5f7 !important;*/
|
||||
/*}*/
|
||||
|
||||
.datatable tr td:first-child, .datatable tr th:first-child, .datatable tr th.ui-state-default:first-child {
|
||||
border-left-width:0 !important;
|
||||
|
@ -3291,3 +3291,82 @@ dd .stream-status {
|
|||
#schedule_iframe {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Show Builder*/
|
||||
|
||||
@media screen and (max-width: 1015px) {
|
||||
.lib-test, .sb-test {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.lib-test legend, .lib-test label, .lib-test span {
|
||||
color: #efefef;
|
||||
}
|
||||
|
||||
.lib-test {
|
||||
margin: 2em 2em 2em 0;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.sb-test {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.lib-test, .sb-test {
|
||||
/* 1em for the middle margin, 6 for half the width of the left pane */
|
||||
width: calc(50% - 8em);
|
||||
min-width: 470px;
|
||||
}
|
||||
|
||||
#media_type_nav {
|
||||
float: left;
|
||||
margin: 2em 0 0 0;
|
||||
|
||||
width: 12em;
|
||||
|
||||
background: none;
|
||||
padding: 0 2em 0 0;
|
||||
}
|
||||
|
||||
#new_media_selector {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.media_type_selector {
|
||||
cursor: pointer;
|
||||
color: #cecece;
|
||||
font-family: Roboto, "Open Sans", sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
width: 100%;
|
||||
margin: 1em 1em 0 0;
|
||||
}
|
||||
|
||||
.media_type_selector.selected {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.media_type_selector:hover {
|
||||
color: #fff;
|
||||
-webkit-transition: color 0.2s linear;
|
||||
-moz-transition: color 0.2s linear;
|
||||
-o-transition: color 0.2s linear;
|
||||
transition: color 0.2s linear;
|
||||
}
|
||||
|
||||
/* Uploads */
|
||||
|
||||
#upload_form {
|
||||
width: 100%;
|
||||
min-width: 470px;
|
||||
|
||||
background: none;
|
||||
border: 2px dashed #efefef;
|
||||
|
||||
color: #efefef;
|
||||
font-family: Roboto, "Open Sans", sans-serif;
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
line-height: 1.4rem;
|
||||
}
|
|
@ -125,7 +125,9 @@ var AIRTIME = (function(AIRTIME) {
|
|||
}
|
||||
|
||||
if (aSchedIds.length == 0) {
|
||||
addToCurrentOrNext(aSchedIds);
|
||||
if (!addToCurrentOrNext(aSchedIds)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds);
|
||||
|
@ -139,6 +141,12 @@ var AIRTIME = (function(AIRTIME) {
|
|||
// the Now Playing screen if multiple shows are in view).
|
||||
el = $("[si_id="+$("#0").attr("si_id")+"]");
|
||||
var temp = el.eq(-2).data("aData");
|
||||
|
||||
if (temp === undefined) {
|
||||
alert($.i18n._("Cannot schedule outside a show."));
|
||||
return false;
|
||||
}
|
||||
|
||||
arr.push({
|
||||
"id" : temp.id,
|
||||
"instance" : temp.instance,
|
||||
|
|
|
@ -0,0 +1,978 @@
|
|||
var AIRTIME = (function(AIRTIME) {
|
||||
var mod,
|
||||
libraryInit,
|
||||
oTable,
|
||||
$libContent,
|
||||
$libTable,
|
||||
LIB_SELECTED_CLASS = "lib-selected",
|
||||
chosenItems = {},
|
||||
visibleChosenItems = {},
|
||||
$previouslySelected;
|
||||
|
||||
|
||||
// we need to know whether the criteria value is string or
|
||||
// numeric in order to provide a single textbox or range textboxes
|
||||
// in the advanced search
|
||||
// s => string
|
||||
// n => numberic
|
||||
var libraryColumnTypes = {
|
||||
0 : "",
|
||||
"album_title" : "s",
|
||||
"artist_name" : "s",
|
||||
"bit_rate" : "n",
|
||||
"bpm" : "n",
|
||||
"comments" : "s",
|
||||
"composer" : "s",
|
||||
"conductor" : "s",
|
||||
"copyright" : "s",
|
||||
"cuein" : "n",
|
||||
"cueout" : "n",
|
||||
"utime" : "n",
|
||||
"mtime" : "n",
|
||||
"lptime" : "n",
|
||||
"disc_number" : "n",
|
||||
"encoded_by" : "s",
|
||||
"genre" : "s",
|
||||
"isrc_number" : "s",
|
||||
"label" : "s",
|
||||
"language" : "s",
|
||||
"length" : "n",
|
||||
"lyricist" : "s",
|
||||
"mime" : "s",
|
||||
"mood" : "s",
|
||||
"name" : "s",
|
||||
"orchestra" : "s",
|
||||
"rating" : "n",
|
||||
"sample_rate" : "n",
|
||||
"track_title" : "s",
|
||||
"track_num" : "n",
|
||||
"year" : "n",
|
||||
"owner_id" : "s",
|
||||
"info_url" : "s",
|
||||
"replay_gain" : "n"
|
||||
};
|
||||
|
||||
if (AIRTIME.library === undefined) {
|
||||
AIRTIME.library = {};
|
||||
}
|
||||
mod = AIRTIME.library;
|
||||
|
||||
mod.getChosenItemsLength = function(){
|
||||
var cItem,
|
||||
selected,
|
||||
$trs;
|
||||
|
||||
// Get visible items and check if any chosenItems are visible
|
||||
$trs = $libTable.find("tr");
|
||||
$trs.each(function(i){
|
||||
for (cItem in chosenItems) {
|
||||
if (cItem === $(this).attr("id")) {
|
||||
visibleChosenItems[cItem] = $(this).data('aData');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
selected = Object.keys(visibleChosenItems).length;
|
||||
visibleChosenItems = {};
|
||||
return selected;
|
||||
};
|
||||
|
||||
mod.getChosenAudioFilesLength = function(){
|
||||
// var files = Object.keys(chosenItems),
|
||||
var files,
|
||||
$trs,
|
||||
cItem,
|
||||
i, length,
|
||||
count = 0,
|
||||
reAudio=/^(au|st|pl|bl)/ ;
|
||||
|
||||
// Get visible items and check if any chosenItems are visible
|
||||
$trs = $libTable.find("tr");
|
||||
$trs.each(function(i){
|
||||
for (cItem in chosenItems) {
|
||||
if (cItem === $(this).attr("id")) {
|
||||
visibleChosenItems[cItem] = $(this).data('aData');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
files = Object.keys(visibleChosenItems);
|
||||
|
||||
for (i = 0, length = files.length; i < length; i++) {
|
||||
|
||||
if (files[i].search(reAudio) !== -1) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
visibleChosenItems = {};
|
||||
return count;
|
||||
};
|
||||
|
||||
mod.changeAddButtonText = function($button, btnText) {
|
||||
$button.text(btnText);
|
||||
};
|
||||
|
||||
mod.createToolbarButtons = function() {
|
||||
$menu = $("<div class='btn-toolbar' />");
|
||||
$menu
|
||||
.append("<div class='btn-group'>" +
|
||||
"<button class='btn btn-small dropdown-toggle' data-toggle='dropdown'>" +
|
||||
$.i18n._("Select")+" <span class='caret'></span>" +
|
||||
"</button>" +
|
||||
"<ul class='dropdown-menu'>" +
|
||||
"<li id='sb-select-page'><a href='#'>"+$.i18n._("Select this page")+"</a></li>" +
|
||||
"<li id='sb-dselect-page'><a href='#'>"+$.i18n._("Deselect this page")+"</a></li>" +
|
||||
"<li id='sb-dselect-all'><a href='#'>"+$.i18n._("Deselect all")+"</a></li>" +
|
||||
"</ul>" +
|
||||
"</div>")
|
||||
.append("<div class='btn-group'>" +
|
||||
"<button class='btn btn-small' id='library-plus'>" +
|
||||
"<i class='icon-white icon-plus'></i>" +
|
||||
"<span id='lib-plus-text'></span>" +
|
||||
"</button>" +
|
||||
"</div>")
|
||||
.append("<div class='btn-group'>" +
|
||||
"<button class='btn btn-small' id='sb-trash'>" +
|
||||
"<i class='icon-white icon-trash'></i>" +
|
||||
"</button>" +
|
||||
"</div>");
|
||||
};
|
||||
|
||||
mod.createToolbarDropDown = function() {
|
||||
$('#sb-select-page').click(function(){mod.selectCurrentPage();});
|
||||
$('#sb-dselect-page').click(function(){mod.deselectCurrentPage();});
|
||||
$('#sb-dselect-all').click(function(){mod.selectNone();});
|
||||
};
|
||||
|
||||
mod.checkDeleteButton = function() {
|
||||
var selected = mod.getChosenItemsLength(),
|
||||
check = false;
|
||||
|
||||
if (selected !== 0) {
|
||||
check = true;
|
||||
}
|
||||
|
||||
if (check === true) {
|
||||
AIRTIME.button.enableButton("btn-group #sb-trash", false);
|
||||
}
|
||||
else {
|
||||
AIRTIME.button.disableButton("btn-group #sb-trash", false);
|
||||
}
|
||||
};
|
||||
|
||||
mod.checkToolBarIcons = function() {
|
||||
|
||||
AIRTIME.library.checkAddButton();
|
||||
AIRTIME.library.checkDeleteButton();
|
||||
};
|
||||
|
||||
mod.getSelectedData = function() {
|
||||
var id,
|
||||
data = [],
|
||||
cItem,
|
||||
$trs;
|
||||
|
||||
$.fn.reverse = [].reverse;
|
||||
|
||||
// Get visible items and check if any chosenItems are visible
|
||||
$trs = $libTable.find("tr").reverse();
|
||||
$trs.each(function(i){
|
||||
for (cItem in chosenItems) {
|
||||
if (cItem === $(this).attr("id")) {
|
||||
visibleChosenItems[cItem] = $(this).data('aData');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (id in visibleChosenItems) {
|
||||
if (visibleChosenItems.hasOwnProperty(id)) {
|
||||
data.push(visibleChosenItems[id]);
|
||||
}
|
||||
}
|
||||
visibleChosenItems = {};
|
||||
return data;
|
||||
};
|
||||
|
||||
mod.redrawChosen = function() {
|
||||
var ids = Object.keys(chosenItems),
|
||||
i, length,
|
||||
$el;
|
||||
|
||||
for (i = 0, length = ids.length; i < length; i++) {
|
||||
$el = $libTable.find("#"+ids[i]);
|
||||
|
||||
if ($el.length !== 0) {
|
||||
mod.highlightItem($el);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mod.isChosenItem = function($el) {
|
||||
var id = $el.attr("id"),
|
||||
item = chosenItems[id];
|
||||
|
||||
return item !== undefined;
|
||||
};
|
||||
|
||||
mod.addToChosen = function($el) {
|
||||
var id = $el.attr("id");
|
||||
|
||||
chosenItems[id] = $el.data('aData');
|
||||
};
|
||||
|
||||
mod.removeFromChosen = function($el) {
|
||||
var id = $el.attr("id");
|
||||
|
||||
// used to not keep dragged items selected.
|
||||
if (!$el.hasClass(LIB_SELECTED_CLASS)) {
|
||||
delete chosenItems[id];
|
||||
}
|
||||
};
|
||||
|
||||
mod.highlightItem = function($el) {
|
||||
$el.addClass(LIB_SELECTED_CLASS);
|
||||
};
|
||||
|
||||
mod.unHighlightItem = function($el) {
|
||||
$el.removeClass(LIB_SELECTED_CLASS);
|
||||
};
|
||||
|
||||
mod.selectItem = function($el) {
|
||||
mod.highlightItem($el);
|
||||
mod.addToChosen($el);
|
||||
|
||||
mod.checkToolBarIcons();
|
||||
};
|
||||
|
||||
mod.deselectItem = function($el) {
|
||||
mod.unHighlightItem($el);
|
||||
mod.removeFromChosen($el);
|
||||
mod.checkToolBarIcons();
|
||||
};
|
||||
|
||||
/*
|
||||
* selects all items which the user can currently see. (behaviour taken from
|
||||
* gmail)
|
||||
*
|
||||
* by default the items are selected in reverse order so we need to reverse
|
||||
* it back
|
||||
*/
|
||||
mod.selectCurrentPage = function() {
|
||||
$.fn.reverse = [].reverse;
|
||||
var $trs = $libTable.find("tbody").find("tr").reverse();
|
||||
$trs.addClass(LIB_SELECTED_CLASS);
|
||||
|
||||
$trs.each(function(i, el){
|
||||
$el = $(this);
|
||||
mod.addToChosen($el);
|
||||
});
|
||||
|
||||
mod.checkToolBarIcons();
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* deselects all items that the user can currently see. (behaviour taken
|
||||
* from gmail)
|
||||
*/
|
||||
mod.deselectCurrentPage = function() {
|
||||
var $trs = $libTable.find("tr"), id;
|
||||
$trs.removeClass(LIB_SELECTED_CLASS);
|
||||
|
||||
$trs.each(function(i, el){
|
||||
$el = $(this);
|
||||
id = $el.attr("id");
|
||||
delete chosenItems[id];
|
||||
});
|
||||
|
||||
mod.checkToolBarIcons();
|
||||
};
|
||||
|
||||
mod.selectNone = function() {
|
||||
var $trs = $libTable.find("tr");
|
||||
$trs.removeClass(LIB_SELECTED_CLASS);
|
||||
|
||||
chosenItems = {};
|
||||
|
||||
mod.checkToolBarIcons();
|
||||
};
|
||||
|
||||
mod.fnDeleteItems = function(aMedia) {
|
||||
|
||||
//Prevent the user from spamming the delete button while the AJAX request is in progress
|
||||
AIRTIME.button.disableButton("btn-group #sb-trash", false);
|
||||
//Hack to immediately show the "Processing" div in DataTables to give the user some sort of feedback.
|
||||
$(".dataTables_processing").css('visibility','visible');
|
||||
|
||||
$.post(baseUrl+"library/delete",
|
||||
{"format": "json", "media": aMedia},
|
||||
function(json){
|
||||
if (json.message !== undefined) {
|
||||
alert(json.message);
|
||||
}
|
||||
|
||||
chosenItems = {};
|
||||
oTable.fnStandingRedraw();
|
||||
|
||||
//Re-enable the delete button
|
||||
AIRTIME.button.enableButton("btn-group #sb-trash", false);
|
||||
});
|
||||
};
|
||||
|
||||
mod.fnDeleteSelectedItems = function() {
|
||||
if (confirm($.i18n._('Are you sure you want to delete the selected item(s)?'))) {
|
||||
var aData = AIRTIME.library.getSelectedData(),
|
||||
item,
|
||||
temp,
|
||||
aMedia = [],
|
||||
currentObjId = $("#side_playlist").find("#obj_id").val(),
|
||||
currentObjType = $("#side_playlist").find("#obj_type").val(),
|
||||
closeObj = false;
|
||||
|
||||
// process selected files/playlists.
|
||||
for (item in aData) {
|
||||
temp = aData[item];
|
||||
if (temp !== null && temp.hasOwnProperty('id') ) {
|
||||
aMedia.push({"id": temp.id, "type": temp.ftype});
|
||||
if ( (temp.id == currentObjId && temp.ftype === currentObjType) ||
|
||||
temp.id == currentObjId && temp.ftype === "stream" && currentObjType === "webstream") {
|
||||
closeObj = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AIRTIME.library.fnDeleteItems(aMedia);
|
||||
|
||||
// close the object (playlist/block/webstream)
|
||||
// on the right side if it was just deleted
|
||||
// from the library
|
||||
if (closeObj) {
|
||||
$.post(baseUrl+"playlist/close-playlist",
|
||||
{"format": "json", "type": currentObjType},
|
||||
function(json) {
|
||||
$("#side_playlist").empty().append(json.html);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
libraryInit = function() {
|
||||
|
||||
$libContent = $("#library_content");
|
||||
|
||||
/*
|
||||
* Icon hover states in the toolbar.
|
||||
*/
|
||||
$libContent.on("mouseenter", ".fg-toolbar ul li", function(ev) {
|
||||
$el = $(this);
|
||||
|
||||
if (!$el.hasClass("ui-state-disabled")) {
|
||||
$el.addClass("ui-state-hover");
|
||||
}
|
||||
});
|
||||
$libContent.on("mouseleave", ".fg-toolbar ul li", function(ev) {
|
||||
$el = $(this);
|
||||
|
||||
if (!$el.hasClass("ui-state-disabled")) {
|
||||
$el.removeClass("ui-state-hover");
|
||||
}
|
||||
});
|
||||
|
||||
var colReorderMap = new Array();
|
||||
|
||||
$libTable = $libContent.find("table");
|
||||
|
||||
function getTableHeight() {
|
||||
return $libContent.height() - 175;
|
||||
}
|
||||
|
||||
function setColumnFilter(oTable){
|
||||
// TODO : remove this dirty hack once js is refactored
|
||||
if (!oTable.fnSettings()) { return ; }
|
||||
var aoCols = oTable.fnSettings().aoColumns;
|
||||
var colsForAdvancedSearch = new Array();
|
||||
var advanceSearchDiv = $("div#advanced_search");
|
||||
advanceSearchDiv.empty();
|
||||
$.each(aoCols, function(i,ele){
|
||||
if (ele.bSearchable) {
|
||||
var currentColId = ele._ColReorder_iOrigCol;
|
||||
|
||||
var inputClass = 'filter_column filter_number_text';
|
||||
var labelStyle = "style='margin-right:35px;'";
|
||||
if (libraryColumnTypes[ele.mDataProp] != "s") {
|
||||
inputClass = 'filterColumn filter_number_range';
|
||||
labelStyle = "";
|
||||
}
|
||||
|
||||
if (ele.bVisible) {
|
||||
advanceSearchDiv.append(
|
||||
"<div id='advanced_search_col_"+currentColId+"' class='control-group'>" +
|
||||
"<label class='control-label'"+labelStyle+">"+ele.sTitle+" : </label>" +
|
||||
"<div id='"+ele.mDataProp+"' class='controls "+inputClass+"'></div>" +
|
||||
"</div>");
|
||||
} else {
|
||||
advanceSearchDiv.append(
|
||||
"<div id='advanced_search_col_"+currentColId+"' class='control-group' style='display:none;'>" +
|
||||
"<label class='control-label'"+labelStyle+">"+ele.sTitle+"</label>" +
|
||||
"<div id='"+ele.mDataProp+"' class='controls "+inputClass+"'></div>" +
|
||||
"</div>");
|
||||
}
|
||||
|
||||
if (libraryColumnTypes[ele.mDataProp] == "s") {
|
||||
var obj = { sSelector: "#"+ele.mDataProp }
|
||||
} else {
|
||||
var obj = { sSelector: "#"+ele.mDataProp, type: "number-range" }
|
||||
}
|
||||
colsForAdvancedSearch.push(obj);
|
||||
} else {
|
||||
colsForAdvancedSearch.push(null);
|
||||
}
|
||||
});
|
||||
|
||||
oTable.columnFilter({
|
||||
aoColumns: colsForAdvancedSearch,
|
||||
bUseColVis: true,
|
||||
sPlaceHolder: "head:before"
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function setFilterElement(iColumn, bVisible){
|
||||
var actualId = colReorderMap[iColumn];
|
||||
var selector = "div#advanced_search_col_"+actualId;
|
||||
var $el = $(selector);
|
||||
|
||||
if (bVisible) {
|
||||
$el.show();
|
||||
} else {
|
||||
$el.hide();
|
||||
}
|
||||
|
||||
//resize to prevent double scroll bars.
|
||||
var $fs = $el.parents("fieldset"),
|
||||
tableHeight = getTableHeight(),
|
||||
searchHeight = $fs.height();
|
||||
|
||||
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight - searchHeight);
|
||||
}
|
||||
|
||||
oTable = $libTable.dataTable( {
|
||||
|
||||
// put hidden columns at the top to insure they can never be visible
|
||||
// on the table through column reordering.
|
||||
|
||||
//IMPORTANT: WHEN ADDING A NEW COLUMN PLEASE CONSULT WITH THE WIKI
|
||||
// https://wiki.sourcefabric.org/display/CC/Adding+a+new+library+datatable+column
|
||||
"aoColumns": [
|
||||
/* ftype */ { "sTitle" : "" , "mDataProp" : "ftype" , "bSearchable" : false , "bVisible" : false } ,
|
||||
/* Type */ { "sTitle" : "" , "mDataProp" : "image" , "bSearchable" : false , "sWidth" : "16px" , "sClass" : "library_type" , "iDataSort" : 0 } ,
|
||||
///* Is Scheduled */ { "sTitle" : $.i18n._("Scheduled") , "mDataProp" : "is_scheduled" , "bVisible" : false , "bSearchable" : false , "sWidth" : "90px" , "sClass" : "library_is_scheduled"} ,
|
||||
/* Is Playlist */ { "sTitle" : $.i18n._("Playlist / Block") , "mDataProp" : "is_playlist" , "bSearchable" : false , "sWidth" : "110px" , "sClass" : "library_is_playlist"} ,
|
||||
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "track_title" , "sClass" : "library_title" , "sWidth" : "170px" } ,
|
||||
/* Creator */ { "sTitle" : $.i18n._("Creator") , "mDataProp" : "artist_name" , "sClass" : "library_creator" , "sWidth" : "160px" } ,
|
||||
/* Album */ { "sTitle" : $.i18n._("Album") , "mDataProp" : "album_title" , "sClass" : "library_album" , "sWidth" : "150px" } ,
|
||||
/* Bit Rate */ { "sTitle" : $.i18n._("Bit Rate") , "mDataProp" : "bit_rate" , "bVisible" : false , "sClass" : "library_bitrate" , "sWidth" : "80px" },
|
||||
/* BPM */ { "sTitle" : $.i18n._("BPM") , "mDataProp" : "bpm" , "bVisible" : false , "sClass" : "library_bpm" , "sWidth" : "50px" },
|
||||
/* Composer */ { "sTitle" : $.i18n._("Composer") , "mDataProp" : "composer" , "bVisible" : false , "sClass" : "library_composer" , "sWidth" : "150px" },
|
||||
/* Conductor */ { "sTitle" : $.i18n._("Conductor") , "mDataProp" : "conductor" , "bVisible" : false , "sClass" : "library_conductor" , "sWidth" : "125px" },
|
||||
/* Copyright */ { "sTitle" : $.i18n._("Copyright") , "mDataProp" : "copyright" , "bVisible" : false , "sClass" : "library_copyright" , "sWidth" : "125px" },
|
||||
/* Cue In */ { "sTitle" : $.i18n._("Cue In") , "mDataProp" : "cuein" , "bVisible" : false , "sClass" : "library_length" , "sWidth" : "80px" },
|
||||
/* Cue Out */ { "sTitle" : $.i18n._("Cue Out") , "mDataProp" : "cueout" , "bVisible" : false , "sClass" : "library_length" , "sWidth" : "80px" },
|
||||
/* Encoded */ { "sTitle" : $.i18n._("Encoded By") , "mDataProp" : "encoded_by" , "bVisible" : false , "sClass" : "library_encoded" , "sWidth" : "150px" },
|
||||
/* Genre */ { "sTitle" : $.i18n._("Genre") , "mDataProp" : "genre" , "bVisible" : false , "sClass" : "library_genre" , "sWidth" : "100px" },
|
||||
/* ISRC Number */ { "sTitle" : $.i18n._("ISRC") , "mDataProp" : "isrc_number" , "bVisible" : false , "sClass" : "library_isrc" , "sWidth" : "150px" },
|
||||
/* Label */ { "sTitle" : $.i18n._("Label") , "mDataProp" : "label" , "bVisible" : false , "sClass" : "library_label" , "sWidth" : "125px" },
|
||||
/* Language */ { "sTitle" : $.i18n._("Language") , "mDataProp" : "language" , "bVisible" : false , "sClass" : "library_language" , "sWidth" : "125px" },
|
||||
/* Last Modified */ { "sTitle" : $.i18n._("Last Modified") , "mDataProp" : "mtime" , "bVisible" : false , "sClass" : "library_modified_time" , "sWidth" : "125px" },
|
||||
/* Last Played */ { "sTitle" : $.i18n._("Last Played") , "mDataProp" : "lptime" , "bVisible" : false , "sClass" : "library_modified_time" , "sWidth" : "125px" },
|
||||
/* Length */ { "sTitle" : $.i18n._("Length") , "mDataProp" : "length" , "sClass" : "library_length" , "sWidth" : "80px" } ,
|
||||
/* Mime */ { "sTitle" : $.i18n._("Mime") , "mDataProp" : "mime" , "bVisible" : false , "sClass" : "library_mime" , "sWidth" : "80px" },
|
||||
/* Mood */ { "sTitle" : $.i18n._("Mood") , "mDataProp" : "mood" , "bVisible" : false , "sClass" : "library_mood" , "sWidth" : "70px" },
|
||||
/* Owner */ { "sTitle" : $.i18n._("Owner") , "mDataProp" : "owner_id" , "bVisible" : false , "sClass" : "library_language" , "sWidth" : "125px" },
|
||||
/* Replay Gain */ { "sTitle" : $.i18n._("Replay Gain") , "mDataProp" : "replay_gain" , "bVisible" : false , "sClass" : "library_replay_gain" , "sWidth" : "80px" },
|
||||
/* Sample Rate */ { "sTitle" : $.i18n._("Sample Rate") , "mDataProp" : "sample_rate" , "bVisible" : false , "sClass" : "library_sr" , "sWidth" : "80px" },
|
||||
/* Track Number */ { "sTitle" : $.i18n._("Track Number") , "mDataProp" : "track_number" , "bVisible" : false , "sClass" : "library_track" , "sWidth" : "65px" },
|
||||
/* Upload Time */ { "sTitle" : $.i18n._("Uploaded") , "mDataProp" : "utime" , "bVisible" : false , "sClass" : "library_upload_time" , "sWidth" : "125px" } ,
|
||||
/* Website */ { "sTitle" : $.i18n._("Website") , "mDataProp" : "info_url" , "bVisible" : false , "sClass" : "library_url" , "sWidth" : "150px" },
|
||||
/* Year */ { "sTitle" : $.i18n._("Year") , "mDataProp" : "year" , "bVisible" : false , "sClass" : "library_year" , "sWidth" : "60px" }
|
||||
],
|
||||
|
||||
"bProcessing": true,
|
||||
"bServerSide": true,
|
||||
|
||||
"aLengthMenu": [[5, 10, 15, 20, 25, 50, 100], [5, 10, 15, 20, 25, 50, 100]],
|
||||
|
||||
"bStateSave": true,
|
||||
"fnStateSaveParams": function (oSettings, oData) {
|
||||
// remove oData components we don't want to save.
|
||||
delete oData.oSearch;
|
||||
delete oData.aoSearchCols;
|
||||
},
|
||||
"fnStateSave": function (oSettings, oData) {
|
||||
localStorage.setItem('datatables-library', JSON.stringify(oData));
|
||||
/*
|
||||
$.ajax({
|
||||
url: baseUrl+"usersettings/set-library-datatable",
|
||||
type: "POST",
|
||||
data: {settings : oData, format: "json"},
|
||||
dataType: "json"
|
||||
});
|
||||
*/
|
||||
|
||||
colReorderMap = oData.ColReorder;
|
||||
},
|
||||
"fnStateLoad": function fnLibStateLoad(oSettings) {
|
||||
var settings = localStorage.getItem('datatables-library');
|
||||
|
||||
try {
|
||||
return JSON.parse(settings);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
"fnStateLoadParams": function (oSettings, oData) {
|
||||
var i,
|
||||
length,
|
||||
a = oData.abVisCols;
|
||||
|
||||
if (a) {
|
||||
// putting serialized data back into the correct js type to make
|
||||
// sure everything works properly.
|
||||
for (i = 0, length = a.length; i < length; i++) {
|
||||
if (typeof(a[i]) === "string") {
|
||||
a[i] = (a[i] === "true") ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a = oData.ColReorder;
|
||||
if (a) {
|
||||
for (i = 0, length = a.length; i < length; i++) {
|
||||
if (typeof(a[i]) === "string") {
|
||||
a[i] = parseInt(a[i], 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oData.iEnd = parseInt(oData.iEnd, 10);
|
||||
oData.iLength = parseInt(oData.iLength, 10);
|
||||
oData.iStart = parseInt(oData.iStart, 10);
|
||||
oData.iCreate = parseInt(oData.iCreate, 10);
|
||||
},
|
||||
|
||||
"sAjaxSource": baseUrl+"Library/contents-feed-test",
|
||||
"sAjaxDataProp": "files",
|
||||
|
||||
"fnServerData": function ( sSource, aoData, fnCallback ) {
|
||||
/*
|
||||
* The real validation check is done in
|
||||
* dataTables.columnFilter.js We also need to check it here
|
||||
* because datatable is redrawn everytime an action is performed
|
||||
* in the Library page. In order for datatable to redraw the
|
||||
* advanced search fields MUST all be valid.
|
||||
*/
|
||||
var advSearchFields = $("div#advanced_search").children(':visible');
|
||||
var advSearchValid = validateAdvancedSearch(advSearchFields);
|
||||
var type;
|
||||
aoData.push( { name: "format", value: "json"} );
|
||||
aoData.push( { name: "advSearch", value: advSearchValid} );
|
||||
|
||||
// push whether to search files/playlists or all.
|
||||
type = $(".media_type_selector.selected").attr("selection_id");
|
||||
type = (type === undefined) ? 1 : type;
|
||||
aoData.push( { name: "type", value: type} );
|
||||
|
||||
$.ajax( {
|
||||
"dataType": 'json',
|
||||
"type": "POST",
|
||||
"url": sSource,
|
||||
"data": aoData,
|
||||
"success": fnCallback
|
||||
} );
|
||||
},
|
||||
"fnRowCallback": AIRTIME.library.fnRowCallback,
|
||||
"fnCreatedRow": function( nRow, aData, iDataIndex ) {
|
||||
// add audio preview image/button
|
||||
if (aData.ftype === "audioclip") {
|
||||
$(nRow).find('td.library_type').html('<img title="'+$.i18n._("Track preview")+'" src="'+baseUrl+'css/images/icon_audioclip.png">');
|
||||
} else if (aData.ftype === "playlist") {
|
||||
$(nRow).find('td.library_type').html('<img title="'+$.i18n._("Playlist preview")+'" src="'+baseUrl+'css/images/icon_playlist.png">');
|
||||
} else if (aData.ftype === "block") {
|
||||
$(nRow).find('td.library_type').html('<img title="'+$.i18n._("Smart Block")+'" src="'+baseUrl+'css/images/icon_smart-block.png">');
|
||||
} else if (aData.ftype === "stream") {
|
||||
$(nRow).find('td.library_type').html('<img title="'+$.i18n._("Webstream preview")+'" src="'+baseUrl+'css/images/icon_webstream.png">');
|
||||
}
|
||||
|
||||
if (aData.is_scheduled) {
|
||||
$(nRow).find("td.library_is_scheduled").html('<span class="small-icon is_scheduled"></span>');
|
||||
} else if (!aData.is_scheduled) {
|
||||
$(nRow).find("td.library_is_scheduled").html('');
|
||||
}
|
||||
if (aData.is_playlist) {
|
||||
$(nRow).find("td.library_is_playlist").html('<span class="small-icon is_playlist"></span>');
|
||||
} else if (!aData.is_playlist) {
|
||||
$(nRow).find("td.library_is_playlist").html('');
|
||||
}
|
||||
|
||||
// add the play function to the library_type td
|
||||
$(nRow).find('td.library_type').click(function(){
|
||||
if (aData.ftype === 'playlist' && aData.length !== '0.0'){
|
||||
open_playlist_preview(aData.audioFile, 0);
|
||||
} else if (aData.ftype === 'audioclip') {
|
||||
if (isAudioSupported(aData.mime)) {
|
||||
open_audio_preview(aData.ftype, aData.id);
|
||||
}
|
||||
} else if (aData.ftype == 'stream') {
|
||||
if (isAudioSupported(aData.mime)) {
|
||||
open_audio_preview(aData.ftype, aData.id);
|
||||
}
|
||||
} else if (aData.ftype == 'block' && aData.bl_type == 'static') {
|
||||
open_block_preview(aData.audioFile, 0);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
// remove any selected nodes before the draw.
|
||||
"fnPreDrawCallback": function( oSettings ) {
|
||||
|
||||
// make sure any dragging helpers are removed or else they'll be
|
||||
// stranded on the screen.
|
||||
$("#draggingContainer").remove();
|
||||
},
|
||||
"fnDrawCallback": AIRTIME.library.fnDrawCallback,
|
||||
|
||||
"aaSorting": [[5, 'asc']],
|
||||
"sPaginationType": "full_numbers",
|
||||
"bJQueryUI": true,
|
||||
"bAutoWidth": false,
|
||||
"oLanguage": datatables_dict,
|
||||
|
||||
// R = ColReorder, C = ColVis
|
||||
"sDom": 'Rl<"#library_display_type">f<"dt-process-rel"r><"H"<"library_toolbar"C>><"dataTables_scrolling"t><"F"ip>',
|
||||
|
||||
"oColVis": {
|
||||
"sAlign": "right",
|
||||
"aiExclude": [0, 1, 2],
|
||||
"sSize": "css",
|
||||
"fnStateChange": setFilterElement,
|
||||
"buttonText": $.i18n._("Show / hide columns")
|
||||
},
|
||||
|
||||
"oColReorder": {
|
||||
"iFixedColumns": 3
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
setColumnFilter(oTable);
|
||||
oTable.fnSetFilteringDelay(350);
|
||||
|
||||
var simpleSearchText;
|
||||
|
||||
$libContent.on("click", "legend", function(){
|
||||
$simpleSearch = $libContent.find("#library_display_filter label");
|
||||
var $fs = $(this).parents("fieldset"),
|
||||
searchHeight,
|
||||
tableHeight = getTableHeight(),
|
||||
height;
|
||||
|
||||
if ($fs.hasClass("closed")) {
|
||||
$fs.removeClass("closed");
|
||||
searchHeight = $fs.height();
|
||||
|
||||
//keep value of simple search for when user switches back to it
|
||||
simpleSearchText = $simpleSearch.find('input').val();
|
||||
|
||||
// clear the simple search text field and reset datatable
|
||||
$(".dataTables_filter input").val("").keyup();
|
||||
|
||||
$simpleSearch.addClass("sp-invisible");
|
||||
|
||||
//resize the library table to avoid a double scroll bar. CC-4504
|
||||
height = tableHeight - searchHeight;
|
||||
$libContent.find(".dataTables_scrolling").css("max-height", height);
|
||||
}
|
||||
else {
|
||||
// clear the advanced search fields
|
||||
var divs = $("div#advanced_search").children(':visible');
|
||||
$.each(divs, function(i, div){
|
||||
fields = $(div).children().find('input');
|
||||
$.each(fields, function(i, field){
|
||||
if ($(field).val() !== "") {
|
||||
$(field).val("");
|
||||
// we need to reset the results when removing
|
||||
// an advanced search field
|
||||
$(field).keyup();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//reset datatable with previous simple search results (if any)
|
||||
$(".dataTables_filter input").val(simpleSearchText).keyup();
|
||||
|
||||
$simpleSearch.removeClass("sp-invisible");
|
||||
$fs.addClass("closed");
|
||||
|
||||
//resize the library table to avoid a double scroll bar. CC-4504
|
||||
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight);
|
||||
}
|
||||
});
|
||||
|
||||
var tableHeight = getTableHeight();
|
||||
$libContent.find(".dataTables_scrolling").css("max-height", tableHeight);
|
||||
|
||||
AIRTIME.library.setupLibraryToolbar(oTable);
|
||||
|
||||
$libTable.find("tbody").on("dblclick", "tr", function(ev) {
|
||||
var $tr = $(this),
|
||||
data = $tr.data("aData");
|
||||
AIRTIME.library.dblClickAdd(data, data.ftype);
|
||||
});
|
||||
|
||||
$libTable.find("tbody").on("click", "tr", function(ev) {
|
||||
var $tr = $(this),
|
||||
// Get the ID of the selected row
|
||||
$rowId = $tr.attr("id");
|
||||
|
||||
if (ev.shiftKey && $previouslySelected !== undefined) {
|
||||
if ($previouslySelected.attr("id") == $rowId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the selected row comes before the previously selected row,
|
||||
// we want to select previous rows, otherwise we select next
|
||||
if ($previouslySelected.prevAll("#"+$rowId).length !== 0) {
|
||||
$previouslySelected.prevUntil($tr).each(function(i, el){
|
||||
mod.selectItem($(el));
|
||||
});
|
||||
} else {
|
||||
$previouslySelected.nextUntil($tr).each(function(i, el){
|
||||
mod.selectItem($(el));
|
||||
});
|
||||
}
|
||||
|
||||
mod.selectItem($tr);
|
||||
} else if (ev.ctrlKey && $previouslySelected !== undefined) {
|
||||
mod.selectItem($tr);
|
||||
} else {
|
||||
$("."+LIB_SELECTED_CLASS).each(function(i, el) {
|
||||
mod.deselectItem($(el))
|
||||
});
|
||||
mod.selectItem($tr);
|
||||
}
|
||||
|
||||
// Remember this row so we can properly multiselect
|
||||
$previouslySelected = $tr;
|
||||
});
|
||||
};
|
||||
mod.libraryInit = libraryInit;
|
||||
|
||||
return AIRTIME;
|
||||
|
||||
}(AIRTIME || {}));
|
||||
|
||||
function buildEditMetadataDialog (json){
|
||||
var dialog = $(json.dialog);
|
||||
|
||||
dialog.dialog({
|
||||
autoOpen: false,
|
||||
title: $.i18n._("Edit Metadata"),
|
||||
width: 460,
|
||||
height: 660,
|
||||
modal: true,
|
||||
close: closeDialogLibrary
|
||||
});
|
||||
|
||||
dialog.dialog('open');
|
||||
}
|
||||
|
||||
function closeDialogLibrary(event, ui) {
|
||||
$(this).remove();
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called from dataTables.columnFilter.js
|
||||
*/
|
||||
function validateAdvancedSearch(divs) {
|
||||
var valid,
|
||||
allValid = true,
|
||||
fieldName,
|
||||
fields,
|
||||
searchTerm = Array(),
|
||||
searchTermType,
|
||||
regExpr,
|
||||
timeRegEx = "\\d{2}[:]([0-5]){1}([0-9]){1}[:]([0-5]){1}([0-9]){1}([.]\\d{1,6})?",
|
||||
dateRegEx = "\\d{4}[-]\\d{2}[-]\\d{2}?",
|
||||
integerRegEx = "^\\d+$",
|
||||
numericRegEx = "^\\d+[.]?\\d*$";
|
||||
|
||||
searchTerm[0] = "";
|
||||
searchTerm[1] = "";
|
||||
$.each(divs, function(i, div){
|
||||
fieldName = $(div).children(':nth-child(2)').attr('id');
|
||||
fields = $(div).children().find('input');
|
||||
searchTermType = validationTypes[fieldName];
|
||||
valid = true;
|
||||
|
||||
$.each(fields, function(i, field){
|
||||
searchTerm[i] = $(field).val();
|
||||
|
||||
if (searchTerm[i] !== "") {
|
||||
|
||||
if (searchTermType === "l") {
|
||||
regExpr = new RegExp("^" +timeRegEx+ "$");
|
||||
} else if (searchTermType === "t") {
|
||||
var pieces = searchTerm[i].split(" ");
|
||||
if (pieces.length === 2) {
|
||||
regExpr = new RegExp("^" +dateRegEx+ " " +timeRegEx+ "$");
|
||||
} else if (pieces.length === 1) {
|
||||
regExpr = new RegExp("^" +dateRegEx+ "$");
|
||||
}
|
||||
} else if (searchTermType === "i") {
|
||||
regExpr = new RegExp(integerRegEx);
|
||||
} else if (searchTermType === "n") {
|
||||
regExpr = new RegExp(numericRegEx);
|
||||
if (searchTerm[i].charAt(0) === "-") {
|
||||
searchTerm[i] = searchTerm[i].substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
// string fields do not need validation
|
||||
if (searchTermType !== "s") {
|
||||
valid = regExpr.test(searchTerm[i]);
|
||||
if (!valid) allValid = false;
|
||||
}
|
||||
|
||||
addRemoveValidationIcons(valid, $(field), searchTermType);
|
||||
|
||||
/*
|
||||
* Empty fields should not have valid/invalid indicator Range values
|
||||
* are considered valid even if only the 'From' value is provided.
|
||||
* Therefore, if the 'To' value is empty but the 'From' value is not
|
||||
* empty we need to keep the validation icon on screen.
|
||||
*/
|
||||
} else if (searchTerm[0] === "" && searchTerm[1] !== "" ||
|
||||
searchTerm[0] === "" && searchTerm[1] === ""){
|
||||
if ($(field).closest('div').children(':last-child').hasClass('checked-icon') ||
|
||||
$(field).closest('div').children(':last-child').hasClass('not-available-icon')) {
|
||||
$(field).closest('div').children(':last-child').remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return allValid;
|
||||
}
|
||||
|
||||
function addRemoveValidationIcons(valid, field, searchTermType) {
|
||||
var title = '';
|
||||
if (searchTermType === 'i') {
|
||||
title = $.i18n._('Input must be a positive number');
|
||||
} else if (searchTermType === 'n') {
|
||||
title = $.i18n._('Input must be a number');
|
||||
} else if (searchTermType === 't') {
|
||||
title = $.i18n._('Input must be in the format: yyyy-mm-dd');
|
||||
} else if (searchTermType === 'l') {
|
||||
title = $.i18n._('Input must be in the format: hh:mm:ss.t');
|
||||
}
|
||||
|
||||
var validIndicator = " <span class='checked-icon sp-checked-icon'></span>",
|
||||
invalidIndicator = " <span title='"+title+"' class='not-available-icon sp-checked-icon'></span>";
|
||||
|
||||
if (valid) {
|
||||
if (!field.closest('div').children(':last-child').hasClass('checked-icon')) {
|
||||
// remove invalid icon before adding valid icon
|
||||
if (field.closest('div').children(':last-child').hasClass('not-available-icon')) {
|
||||
field.closest('div').children(':last-child').remove();
|
||||
}
|
||||
field.closest('div').append(validIndicator);
|
||||
}
|
||||
} else {
|
||||
if (!field.closest('div').children(':last-child').hasClass('not-available-icon')) {
|
||||
// remove valid icon before adding invalid icon
|
||||
if (field.closest('div').children(':last-child').hasClass('checked-icon')) {
|
||||
field.closest('div').children(':last-child').remove();
|
||||
}
|
||||
field.closest('div').append(invalidIndicator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Validation types: s => string i => integer n => numeric (positive/negative,
|
||||
* whole/decimals) t => timestamp l => length
|
||||
*/
|
||||
var validationTypes = {
|
||||
"album_title" : "s",
|
||||
"artist_name" : "s",
|
||||
"bit_rate" : "i",
|
||||
"bpm" : "i",
|
||||
"comments" : "s",
|
||||
"composer" : "s",
|
||||
"conductor" : "s",
|
||||
"copyright" : "s",
|
||||
"cuein" : "l",
|
||||
"cueout" : "l",
|
||||
"encoded_by" : "s",
|
||||
"utime" : "t",
|
||||
"mtime" : "t",
|
||||
"lptime" : "t",
|
||||
"disc_number" : "i",
|
||||
"genre" : "s",
|
||||
"isrc_number" : "s",
|
||||
"label" : "s",
|
||||
"language" : "s",
|
||||
"length" : "l",
|
||||
"lyricist" : "s",
|
||||
"mood" : "s",
|
||||
"mime" : "s",
|
||||
"name" : "s",
|
||||
"orchestra" : "s",
|
||||
"owner_id" : "s",
|
||||
"rating" : "i",
|
||||
"replay_gain" : "n",
|
||||
"sample_rate" : "n",
|
||||
"track_title" : "s",
|
||||
"track_number" : "i",
|
||||
"info_url" : "s",
|
||||
"year" : "i"
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#editmdsave').live("click", function() {
|
||||
var file_id = $('#file_id').val(),
|
||||
data = $("#edit-md-dialog form").serializeArray();
|
||||
$.post(baseUrl+'library/edit-file-md', {format: "json", id: file_id, data: data}, function() {
|
||||
$("#edit-md-dialog").dialog().remove();
|
||||
|
||||
// don't redraw the library table if we are on calendar page
|
||||
// we would be on calendar if viewing recorded file metadata
|
||||
if ($("#schedule_calendar").length === 0) {
|
||||
oTable.fnStandingRedraw();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#editmdcancel').live("click", function() {
|
||||
$("#edit-md-dialog").dialog().remove();
|
||||
});
|
||||
|
||||
$('#edit-md-dialog').live("keyup", function(event) {
|
||||
if (event.keyCode === 13) {
|
||||
$('#editmdsave').click();
|
||||
}
|
||||
});
|
||||
|
||||
$(".media_type_selector").on("click", function() {
|
||||
$(".media_type_selector").each(function() {
|
||||
$(this).removeClass("selected");
|
||||
});
|
||||
$(this).addClass("selected");
|
||||
oTable.fnDraw();
|
||||
});
|
||||
});
|
||||
|
|
@ -484,35 +484,35 @@ var AIRTIME = (function(AIRTIME) {
|
|||
//IMPORTANT: WHEN ADDING A NEW COLUMN PLEASE CONSULT WITH THE WIKI
|
||||
// https://wiki.sourcefabric.org/display/CC/Adding+a+new+library+datatable+column
|
||||
"aoColumns": [
|
||||
/* ftype */ { "sTitle" : "" , "mDataProp" : "ftype" , "bSearchable" : false , "bVisible" : false } ,
|
||||
/* Checkbox */ { "sTitle" : "" , "mDataProp" : "checkbox" , "bSortable" : false , "bSearchable" : false , "sWidth" : "25px" , "sClass" : "library_checkbox" } ,
|
||||
/* ftype */ { "sTitle" : "" , "mDataProp" : "ftype" , "bSearchable" : false , "bVisible" : false } ,
|
||||
/* Checkbox */ { "sTitle" : "" , "mDataProp" : "checkbox" , "bSortable" : false , "bSearchable" : false , "sWidth" : "25px" , "sClass" : "library_checkbox" } ,
|
||||
/* Type */ { "sTitle" : "" , "mDataProp" : "image" , "bSearchable" : false , "sWidth" : "25px" , "sClass" : "library_type" , "iDataSort" : 0 } ,
|
||||
/* Is Scheduled */ { "sTitle" : $.i18n._("Scheduled") , "mDataProp" : "is_scheduled" , "bSearchable" : false , "sWidth" : "90px" , "sClass" : "library_is_scheduled"} ,
|
||||
/* Is Playlist */ { "sTitle" : $.i18n._("Playlist / Block") , "mDataProp" : "is_playlist" , "bSearchable" : false , "sWidth" : "110px" , "sClass" : "library_is_playlist"} ,
|
||||
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "track_title" , "sClass" : "library_title" , "sWidth" : "170px" } ,
|
||||
/* Creator */ { "sTitle" : $.i18n._("Creator") , "mDataProp" : "artist_name" , "sClass" : "library_creator" , "sWidth" : "160px" } ,
|
||||
/* Album */ { "sTitle" : $.i18n._("Album") , "mDataProp" : "album_title" , "sClass" : "library_album" , "sWidth" : "150px" } ,
|
||||
/* Bit Rate */ { "sTitle" : $.i18n._("Bit Rate") , "mDataProp" : "bit_rate" , "bVisible" : false , "sClass" : "library_bitrate" , "sWidth" : "80px" },
|
||||
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "track_title" , "sClass" : "library_title" , "sWidth" : "170px" } ,
|
||||
/* Creator */ { "sTitle" : $.i18n._("Creator") , "mDataProp" : "artist_name" , "sClass" : "library_creator" , "sWidth" : "160px" } ,
|
||||
/* Album */ { "sTitle" : $.i18n._("Album") , "mDataProp" : "album_title" , "sClass" : "library_album" , "sWidth" : "150px" } ,
|
||||
/* Bit Rate */ { "sTitle" : $.i18n._("Bit Rate") , "mDataProp" : "bit_rate" , "bVisible" : false , "sClass" : "library_bitrate" , "sWidth" : "80px" },
|
||||
/* BPM */ { "sTitle" : $.i18n._("BPM") , "mDataProp" : "bpm" , "bVisible" : false , "sClass" : "library_bpm" , "sWidth" : "50px" },
|
||||
/* Composer */ { "sTitle" : $.i18n._("Composer") , "mDataProp" : "composer" , "bVisible" : false , "sClass" : "library_composer" , "sWidth" : "150px" },
|
||||
/* Composer */ { "sTitle" : $.i18n._("Composer") , "mDataProp" : "composer" , "bVisible" : false , "sClass" : "library_composer" , "sWidth" : "150px" },
|
||||
/* Conductor */ { "sTitle" : $.i18n._("Conductor") , "mDataProp" : "conductor" , "bVisible" : false , "sClass" : "library_conductor" , "sWidth" : "125px" },
|
||||
/* Copyright */ { "sTitle" : $.i18n._("Copyright") , "mDataProp" : "copyright" , "bVisible" : false , "sClass" : "library_copyright" , "sWidth" : "125px" },
|
||||
/* Cue In */ { "sTitle" : $.i18n._("Cue In") , "mDataProp" : "cuein" , "bVisible" : false , "sClass" : "library_length" , "sWidth" : "80px" },
|
||||
/* Cue Out */ { "sTitle" : $.i18n._("Cue Out") , "mDataProp" : "cueout" , "bVisible" : false , "sClass" : "library_length" , "sWidth" : "80px" },
|
||||
/* Encoded */ { "sTitle" : $.i18n._("Encoded By") , "mDataProp" : "encoded_by" , "bVisible" : false , "sClass" : "library_encoded" , "sWidth" : "150px" },
|
||||
/* Genre */ { "sTitle" : $.i18n._("Genre") , "mDataProp" : "genre" , "bVisible" : false , "sClass" : "library_genre" , "sWidth" : "100px" },
|
||||
/* ISRC Number */ { "sTitle" : $.i18n._("ISRC") , "mDataProp" : "isrc_number" , "bVisible" : false , "sClass" : "library_isrc" , "sWidth" : "150px" },
|
||||
/* Label */ { "sTitle" : $.i18n._("Label") , "mDataProp" : "label" , "bVisible" : false , "sClass" : "library_label" , "sWidth" : "125px" },
|
||||
/* Language */ { "sTitle" : $.i18n._("Language") , "mDataProp" : "language" , "bVisible" : false , "sClass" : "library_language" , "sWidth" : "125px" },
|
||||
/* Encoded */ { "sTitle" : $.i18n._("Encoded By") , "mDataProp" : "encoded_by" , "bVisible" : false , "sClass" : "library_encoded" , "sWidth" : "150px" },
|
||||
/* Genre */ { "sTitle" : $.i18n._("Genre") , "mDataProp" : "genre" , "bVisible" : false , "sClass" : "library_genre" , "sWidth" : "100px" },
|
||||
/* ISRC Number */ { "sTitle" : $.i18n._("ISRC") , "mDataProp" : "isrc_number" , "bVisible" : false , "sClass" : "library_isrc" , "sWidth" : "150px" },
|
||||
/* Label */ { "sTitle" : $.i18n._("Label") , "mDataProp" : "label" , "bVisible" : false , "sClass" : "library_label" , "sWidth" : "125px" },
|
||||
/* Language */ { "sTitle" : $.i18n._("Language") , "mDataProp" : "language" , "bVisible" : false , "sClass" : "library_language" , "sWidth" : "125px" },
|
||||
/* Last Modified */ { "sTitle" : $.i18n._("Last Modified") , "mDataProp" : "mtime" , "bVisible" : false , "sClass" : "library_modified_time" , "sWidth" : "125px" },
|
||||
/* Last Played */ { "sTitle" : $.i18n._("Last Played") , "mDataProp" : "lptime" , "bVisible" : false , "sClass" : "library_modified_time" , "sWidth" : "125px" },
|
||||
/* Length */ { "sTitle" : $.i18n._("Length") , "mDataProp" : "length" , "sClass" : "library_length" , "sWidth" : "80px" } ,
|
||||
/* Mime */ { "sTitle" : $.i18n._("Mime") , "mDataProp" : "mime" , "bVisible" : false , "sClass" : "library_mime" , "sWidth" : "80px" },
|
||||
/* Last Played */ { "sTitle" : $.i18n._("Last Played") , "mDataProp" : "lptime" , "bVisible" : false , "sClass" : "library_modified_time" , "sWidth" : "125px" },
|
||||
/* Length */ { "sTitle" : $.i18n._("Length") , "mDataProp" : "length" , "sClass" : "library_length" , "sWidth" : "80px" } ,
|
||||
/* Mime */ { "sTitle" : $.i18n._("Mime") , "mDataProp" : "mime" , "bVisible" : false , "sClass" : "library_mime" , "sWidth" : "80px" },
|
||||
/* Mood */ { "sTitle" : $.i18n._("Mood") , "mDataProp" : "mood" , "bVisible" : false , "sClass" : "library_mood" , "sWidth" : "70px" },
|
||||
/* Owner */ { "sTitle" : $.i18n._("Owner") , "mDataProp" : "owner_id" , "bVisible" : false , "sClass" : "library_language" , "sWidth" : "125px" },
|
||||
/* Replay Gain */ { "sTitle" : $.i18n._("Replay Gain") , "mDataProp" : "replay_gain" , "bVisible" : false , "sClass" : "library_replay_gain" , "sWidth" : "80px" },
|
||||
/* Sample Rate */ { "sTitle" : $.i18n._("Sample Rate") , "mDataProp" : "sample_rate" , "bVisible" : false , "sClass" : "library_sr" , "sWidth" : "80px" },
|
||||
/* Track Number */ { "sTitle" : $.i18n._("Track Number") , "mDataProp" : "track_number" , "bVisible" : false , "sClass" : "library_track" , "sWidth" : "65px" },
|
||||
/* Owner */ { "sTitle" : $.i18n._("Owner") , "mDataProp" : "owner_id" , "bVisible" : false , "sClass" : "library_language" , "sWidth" : "125px" },
|
||||
/* Replay Gain */ { "sTitle" : $.i18n._("Replay Gain") , "mDataProp" : "replay_gain" , "bVisible" : false , "sClass" : "library_replay_gain" , "sWidth" : "80px" },
|
||||
/* Sample Rate */ { "sTitle" : $.i18n._("Sample Rate") , "mDataProp" : "sample_rate" , "bVisible" : false , "sClass" : "library_sr" , "sWidth" : "80px" },
|
||||
/* Track Number */ { "sTitle" : $.i18n._("Track Number") , "mDataProp" : "track_number" , "bVisible" : false , "sClass" : "library_track" , "sWidth" : "65px" },
|
||||
/* Upload Time */ { "sTitle" : $.i18n._("Uploaded") , "mDataProp" : "utime" , "sClass" : "library_upload_time" , "sWidth" : "125px" } ,
|
||||
/* Website */ { "sTitle" : $.i18n._("Website") , "mDataProp" : "info_url" , "bVisible" : false , "sClass" : "library_url" , "sWidth" : "150px" },
|
||||
/* Year */ { "sTitle" : $.i18n._("Year") , "mDataProp" : "year" , "bVisible" : false , "sClass" : "library_year" , "sWidth" : "60px" }
|
||||
|
|
|
@ -214,7 +214,7 @@ var AIRTIME = (function(AIRTIME){
|
|||
aData = [],
|
||||
i, length,
|
||||
$item;
|
||||
|
||||
|
||||
if (sNot !== undefined) {
|
||||
$selected = $selected.not("."+sNot);
|
||||
}
|
||||
|
@ -1065,6 +1065,10 @@ var AIRTIME = (function(AIRTIME){
|
|||
var elements = $sbTable.find('tr input:checked').parents('tr').not("."+NOW_PLAYING_CLASS);
|
||||
|
||||
elements.hide();
|
||||
},
|
||||
stop: function() {
|
||||
var elements = $sbTable.find('tr.'+SB_SELECTED_CLASS).not("."+NOW_PLAYING_CLASS);
|
||||
elements.show();
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,347 @@
|
|||
AIRTIME = (function(AIRTIME) {
|
||||
|
||||
var viewport,
|
||||
$lib,
|
||||
$libWrapper,
|
||||
$builder,
|
||||
$fs,
|
||||
widgetHeight,
|
||||
screenWidth,
|
||||
resizeTimeout,
|
||||
oBaseDatePickerSettings,
|
||||
oBaseTimePickerSettings,
|
||||
oRange,
|
||||
dateStartId = "#sb_date_start",
|
||||
timeStartId = "#sb_time_start",
|
||||
dateEndId = "#sb_date_end",
|
||||
timeEndId = "#sb_time_end",
|
||||
mod;
|
||||
|
||||
if (AIRTIME.builderMain === undefined) {
|
||||
AIRTIME.builderMain = {};
|
||||
}
|
||||
mod = AIRTIME.builderMain;
|
||||
|
||||
oBaseDatePickerSettings = {
|
||||
dateFormat: 'yy-mm-dd',
|
||||
//i18n_months, i18n_days_short are in common.js
|
||||
monthNames: i18n_months,
|
||||
dayNamesMin: i18n_days_short,
|
||||
onClick: function(sDate, oDatePicker) {
|
||||
$(this).datepicker( "setDate", sDate );
|
||||
},
|
||||
onClose: validateTimeRange
|
||||
};
|
||||
|
||||
oBaseTimePickerSettings = {
|
||||
showPeriodLabels: false,
|
||||
showCloseButton: true,
|
||||
closeButtonText: $.i18n._("Done"),
|
||||
showLeadingZero: false,
|
||||
defaultTime: '0:00',
|
||||
hourText: $.i18n._("Hour"),
|
||||
minuteText: $.i18n._("Minute"),
|
||||
onClose: validateTimeRange
|
||||
};
|
||||
|
||||
function setWidgetSize() {
|
||||
viewport = AIRTIME.utilities.findViewportDimensions();
|
||||
widgetHeight = viewport.height - 180;
|
||||
screenWidth = Math.floor(viewport.width - 50);
|
||||
|
||||
var libTableHeight = widgetHeight - 175,
|
||||
builderTableHeight = widgetHeight - 95,
|
||||
oTable;
|
||||
|
||||
if ($fs.is(':visible')) {
|
||||
builderTableHeight = builderTableHeight - 40;
|
||||
}
|
||||
|
||||
//set the heights of the main widgets.
|
||||
$builder//.height(widgetHeight)
|
||||
.find(".dataTables_scrolling")
|
||||
.css("max-height", builderTableHeight)
|
||||
.end();
|
||||
//.width(screenWidth);
|
||||
|
||||
$lib//.height(widgetHeight)
|
||||
.find(".dataTables_scrolling")
|
||||
.css("max-height", libTableHeight)
|
||||
.end();
|
||||
|
||||
if ($lib.filter(':visible').length > 0) {
|
||||
|
||||
//$lib.width(Math.floor(screenWidth * 0.47));
|
||||
|
||||
$builder//.width(Math.floor(screenWidth * 0.47))
|
||||
.find("#sb_edit")
|
||||
.remove()
|
||||
.end()
|
||||
.find("#sb_date_start")
|
||||
.css("margin-left", 0)
|
||||
.end();
|
||||
|
||||
oTable = $('#show_builder_table').dataTable();
|
||||
//oTable.fnDraw();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
function showSearchSubmit() {
|
||||
var fn,
|
||||
op,
|
||||
oTable = $('#show_builder_table').dataTable(),
|
||||
check;
|
||||
|
||||
check = validateTimeRange();
|
||||
|
||||
if (check.isValid) {
|
||||
|
||||
//reset timestamp value since input values could have changed.
|
||||
AIRTIME.showbuilder.resetTimestamp();
|
||||
|
||||
fn = oTable.fnSettings().fnServerData;
|
||||
fn.start = check.start;
|
||||
fn.end = check.end;
|
||||
|
||||
op = $("div.sb-advanced-options");
|
||||
if (op.is(":visible")) {
|
||||
|
||||
if (fn.ops === undefined) {
|
||||
fn.ops = {};
|
||||
}
|
||||
fn.ops.showFilter = op.find("#sb_show_filter").val();
|
||||
fn.ops.myShows = op.find("#sb_my_shows").is(":checked") ? 1 : 0;
|
||||
}
|
||||
|
||||
oTable.fnDraw();
|
||||
}
|
||||
}
|
||||
|
||||
mod.onReady = function() {
|
||||
|
||||
Dropzone.options.uploadForm = {
|
||||
init: function () {
|
||||
this.on("sending", function (file, xhr, data) {
|
||||
data.append("csrf_token", $("#csrf").val());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// define module vars.
|
||||
$lib = $("#library_content");
|
||||
$builder = $("#show_builder");
|
||||
$fs = $builder.find('fieldset');
|
||||
|
||||
/*
|
||||
* Icon hover states for search.
|
||||
*/
|
||||
$builder.on("mouseenter", ".sb-timerange .ui-button", function(ev) {
|
||||
$(this).addClass("ui-state-hover");
|
||||
});
|
||||
$builder.on("mouseleave", ".sb-timerange .ui-button", function(ev) {
|
||||
$(this).removeClass("ui-state-hover");
|
||||
});
|
||||
|
||||
$builder.find(dateStartId)
|
||||
.datepicker(oBaseDatePickerSettings)
|
||||
.blur(validateTimeRange);
|
||||
|
||||
$builder.find(timeStartId)
|
||||
.timepicker(oBaseTimePickerSettings)
|
||||
.blur(validateTimeRange);
|
||||
|
||||
$builder.find(dateEndId)
|
||||
.datepicker(oBaseDatePickerSettings)
|
||||
.blur(validateTimeRange);
|
||||
|
||||
$builder.find(timeEndId)
|
||||
.timepicker(oBaseTimePickerSettings)
|
||||
.blur(validateTimeRange);
|
||||
|
||||
|
||||
oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId,
|
||||
dateEndId, timeEndId);
|
||||
AIRTIME.showbuilder.fnServerData.start = oRange.start;
|
||||
AIRTIME.showbuilder.fnServerData.end = oRange.end;
|
||||
|
||||
//the user might not have the library on the page (guest user)
|
||||
if (AIRTIME.library !== undefined) {
|
||||
AIRTIME.library.libraryInit();
|
||||
}
|
||||
|
||||
AIRTIME.showbuilder.builderDataTable();
|
||||
setWidgetSize();
|
||||
|
||||
$libWrapper = $lib.find("#library_display_wrapper");
|
||||
$builder.find('.dataTables_scrolling').css("max-height",
|
||||
widgetHeight - 95);
|
||||
|
||||
$builder.on("click", "#sb_submit", showSearchSubmit);
|
||||
|
||||
$builder.on("click", "#sb_edit", function(ev) {
|
||||
var schedTable = $("#show_builder_table").dataTable();
|
||||
|
||||
// reset timestamp to redraw the cursors.
|
||||
AIRTIME.showbuilder.resetTimestamp();
|
||||
|
||||
$lib.show().width(Math.floor(screenWidth * 0.48));
|
||||
|
||||
$builder.width(Math.floor(screenWidth * 0.48)).find("#sb_edit")
|
||||
.remove().end().find("#sb_date_start")
|
||||
.css("margin-left", 0).end();
|
||||
|
||||
schedTable.fnDraw();
|
||||
|
||||
$.ajax( {
|
||||
url : baseUrl+"usersettings/set-now-playing-screen-settings",
|
||||
type : "POST",
|
||||
data : {
|
||||
settings : {
|
||||
library : true
|
||||
},
|
||||
format : "json"
|
||||
},
|
||||
dataType : "json",
|
||||
success : function() {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$lib.on("click", "#sb_lib_close", function() {
|
||||
var schedTable = $("#show_builder_table").dataTable();
|
||||
|
||||
$lib.hide();
|
||||
$builder.width(screenWidth).find(".sb-timerange").find("#sb_date_start").css("margin-left", 30)
|
||||
.end().end();
|
||||
|
||||
schedTable.fnDraw();
|
||||
|
||||
$.ajax( {
|
||||
url : baseUrl+"usersettings/set-now-playing-screen-settings",
|
||||
type : "POST",
|
||||
data : {
|
||||
settings : {
|
||||
library : false
|
||||
},
|
||||
format : "json"
|
||||
},
|
||||
dataType : "json",
|
||||
success : function() {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$builder.find('legend').click(
|
||||
function(ev, item) {
|
||||
|
||||
if ($fs.hasClass("closed")) {
|
||||
|
||||
$fs.removeClass("closed");
|
||||
$builder.find('.dataTables_scrolling').css(
|
||||
"max-height", widgetHeight - 150);
|
||||
} else {
|
||||
$fs.addClass("closed");
|
||||
|
||||
// set defaults for the options.
|
||||
$fs.find('select').val(0);
|
||||
$fs.find('input[type="checkbox"]').attr("checked",
|
||||
false);
|
||||
$builder.find('.dataTables_scrolling').css(
|
||||
"max-height", widgetHeight - 110);
|
||||
}
|
||||
});
|
||||
|
||||
// set click event for all my shows checkbox.
|
||||
$builder.on("click", "#sb_my_shows", function(ev) {
|
||||
|
||||
if ($(this).is(':checked')) {
|
||||
$(ev.delegateTarget).find('#sb_show_filter').val(0);
|
||||
}
|
||||
|
||||
showSearchSubmit();
|
||||
});
|
||||
|
||||
//set select event for choosing a show.
|
||||
$builder.on("change", '#sb_show_filter', function(ev) {
|
||||
|
||||
if ($(this).val() !== 0) {
|
||||
$(ev.delegateTarget).find('#sb_my_shows')
|
||||
.attr("checked", false);
|
||||
}
|
||||
|
||||
showSearchSubmit();
|
||||
|
||||
});
|
||||
|
||||
function checkScheduleUpdates() {
|
||||
var data = {}, oTable = $('#show_builder_table').dataTable(), fn = oTable
|
||||
.fnSettings().fnServerData, start = fn.start, end = fn.end;
|
||||
|
||||
data["format"] = "json";
|
||||
data["start"] = start;
|
||||
data["end"] = end;
|
||||
data["timestamp"] = AIRTIME.showbuilder.getTimestamp();
|
||||
data["instances"] = AIRTIME.showbuilder.getShowInstances();
|
||||
|
||||
if (fn.hasOwnProperty("ops")) {
|
||||
data["myShows"] = fn.ops.myShows;
|
||||
data["showFilter"] = fn.ops.showFilter;
|
||||
data["showInstanceFilter"] = fn.ops.showInstanceFilter;
|
||||
}
|
||||
|
||||
$.ajax( {
|
||||
"dataType" : "json",
|
||||
"type" : "GET",
|
||||
"url" : baseUrl+"showbuilder/check-builder-feed",
|
||||
"data" : data,
|
||||
"success" : function(json) {
|
||||
if (json.update === true) {
|
||||
oTable.fnDraw();
|
||||
}
|
||||
setTimeout(checkScheduleUpdates, 5000);
|
||||
}
|
||||
});
|
||||
|
||||
//check if the timeline view needs updating.
|
||||
setTimeout(checkScheduleUpdates, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
mod.onResize = function() {
|
||||
|
||||
clearTimeout(resizeTimeout);
|
||||
resizeTimeout = setTimeout(setWidgetSize, 100);
|
||||
};
|
||||
|
||||
return AIRTIME;
|
||||
|
||||
} (AIRTIME || {}));
|
||||
|
||||
$(document).ready(AIRTIME.builderMain.onReady);
|
||||
$(window).resize(AIRTIME.builderMain.onResize);
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue