Merge branch 'saas-dev-publishing' of https://github.com/sourcefabric/Airtime into saas-dev-publishing
This commit is contained in:
commit
2ede56c26d
|
@ -33,7 +33,7 @@ require_once "TaskManager.php";
|
||||||
require_once "UsabilityHints.php";
|
require_once "UsabilityHints.php";
|
||||||
require_once "MediaType.php";
|
require_once "MediaType.php";
|
||||||
require_once __DIR__.'/models/formatters/LengthFormatter.php';
|
require_once __DIR__.'/models/formatters/LengthFormatter.php';
|
||||||
require_once __DIR__.'/services/CeleryService.php';
|
require_once __DIR__.'/services/CeleryManager.php';
|
||||||
require_once __DIR__.'/services/SoundcloudService.php';
|
require_once __DIR__.'/services/SoundcloudService.php';
|
||||||
require_once __DIR__.'/forms/helpers/ValidationTypes.php';
|
require_once __DIR__.'/forms/helpers/ValidationTypes.php';
|
||||||
require_once __DIR__.'/forms/helpers/CustomDecorators.php';
|
require_once __DIR__.'/forms/helpers/CustomDecorators.php';
|
||||||
|
|
|
@ -237,14 +237,14 @@ class CeleryTask implements AirtimeTask {
|
||||||
* @return bool true if there are pending tasks in ThirdPartyTrackReferences
|
* @return bool true if there are pending tasks in ThirdPartyTrackReferences
|
||||||
*/
|
*/
|
||||||
public function shouldBeRun() {
|
public function shouldBeRun() {
|
||||||
return !CeleryService::isBrokerTaskQueueEmpty();
|
return !CeleryManager::isBrokerTaskQueueEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Poll the task queue for any completed Celery tasks
|
* Poll the task queue for any completed Celery tasks
|
||||||
*/
|
*/
|
||||||
public function run() {
|
public function run() {
|
||||||
CeleryService::pollBrokerTaskQueue();
|
CeleryManager::pollBrokerTaskQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -56,6 +56,7 @@ class ShowbuilderController extends Zend_Controller_Action
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/libs/dropzone.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/libs/dropzone.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
|
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$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/tabs.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/main_builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/main_builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require_once "CeleryServiceFactory.php";
|
require_once "CeleryServiceFactory.php";
|
||||||
|
|
||||||
class CeleryService {
|
class CeleryManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int milliseconds (for compatibility with celery) until we consider a message to have timed out
|
* @var int milliseconds (for compatibility with celery) until we consider a message to have timed out
|
|
@ -24,6 +24,30 @@ abstract class ThirdPartyCeleryService extends ThirdPartyService {
|
||||||
*/
|
*/
|
||||||
protected static $_CELERY_DELETE_TASK_NAME;
|
protected static $_CELERY_DELETE_TASK_NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a Celery task with the given name and data parameters
|
||||||
|
*
|
||||||
|
* FIXME: Currently, downloads will not create task reference rows because they
|
||||||
|
* don't have a valid file identifier - this means that we will never know if there
|
||||||
|
* is an issue with the download before the callback to /rest/media is called!
|
||||||
|
*
|
||||||
|
* @param string $taskName the name of the celery task to execute
|
||||||
|
* @param array $data the data array to send as task parameters
|
||||||
|
* @param int $fileId the unique identifier for the file involved in the task
|
||||||
|
*/
|
||||||
|
protected function _executeTask($taskName, $data, $fileId) {
|
||||||
|
try {
|
||||||
|
$brokerTaskId = CeleryManager::sendCeleryMessage($taskName,
|
||||||
|
static::$_CELERY_EXCHANGE_NAME,
|
||||||
|
$data);
|
||||||
|
if (!empty($fileId)) {
|
||||||
|
$this->_createTaskReference($fileId, $brokerTaskId, $taskName);
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Logging::info("Invalid request: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload the file with the given identifier to a third-party service
|
* Upload the file with the given identifier to a third-party service
|
||||||
*
|
*
|
||||||
|
@ -36,20 +60,13 @@ abstract class ThirdPartyCeleryService extends ThirdPartyService {
|
||||||
'token' => $this->_accessToken,
|
'token' => $this->_accessToken,
|
||||||
'file_path' => $file->getFilePaths()[0]
|
'file_path' => $file->getFilePaths()[0]
|
||||||
);
|
);
|
||||||
try {
|
$this->_executeTask(static::$_CELERY_UPLOAD_TASK_NAME, $data, $fileId);
|
||||||
$brokerTaskId = CeleryService::sendCeleryMessage(static::$_CELERY_UPLOAD_TASK_NAME,
|
|
||||||
static::$_CELERY_EXCHANGE_NAME,
|
|
||||||
$data);
|
|
||||||
$this->_createTaskReference($fileId, $brokerTaskId, static::$_CELERY_UPLOAD_TASK_NAME);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
Logging::info("Invalid request: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a track identifier, download a track from a third-party service.
|
* Given a track identifier, download a track from a third-party service.
|
||||||
*
|
*
|
||||||
* @param int|null $trackId a track identifier
|
* @param int $trackId a track identifier
|
||||||
*/
|
*/
|
||||||
public function download($trackId) {
|
public function download($trackId) {
|
||||||
$namespace = new Zend_Session_Namespace('csrf_namespace');
|
$namespace = new Zend_Session_Namespace('csrf_namespace');
|
||||||
|
@ -59,13 +76,9 @@ abstract class ThirdPartyCeleryService extends ThirdPartyService {
|
||||||
'token' => $this->_accessToken,
|
'token' => $this->_accessToken,
|
||||||
'track_id' => $trackId
|
'track_id' => $trackId
|
||||||
);
|
);
|
||||||
try {
|
// FIXME
|
||||||
CeleryService::sendCeleryMessage(static::$_CELERY_DOWNLOAD_TASK_NAME,
|
Logging::warn("FIXME: we can't create a task reference without a valid file ID");
|
||||||
static::$_CELERY_EXCHANGE_NAME,
|
$this->_executeTask(static::$_CELERY_DOWNLOAD_TASK_NAME, $data, null);
|
||||||
$data);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
Logging::info("Invalid request: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,14 +98,7 @@ abstract class ThirdPartyCeleryService extends ThirdPartyService {
|
||||||
'token' => $this->_accessToken,
|
'token' => $this->_accessToken,
|
||||||
'track_id' => $serviceId
|
'track_id' => $serviceId
|
||||||
);
|
);
|
||||||
try {
|
$this->_executeTask(static::$_CELERY_DELETE_TASK_NAME, $data, $fileId);
|
||||||
$brokerTaskId = CeleryService::sendCeleryMessage(static::$_CELERY_DELETE_TASK_NAME,
|
|
||||||
static::$_CELERY_EXCHANGE_NAME,
|
|
||||||
$data);
|
|
||||||
$this->_createTaskReference($fileId, $brokerTaskId, static::$_CELERY_DELETE_TASK_NAME);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
Logging::info("Invalid request: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,19 +114,19 @@ abstract class ThirdPartyCeleryService extends ThirdPartyService {
|
||||||
* @throws PropelException
|
* @throws PropelException
|
||||||
*/
|
*/
|
||||||
protected function _createTaskReference($fileId, $brokerTaskId, $taskName) {
|
protected function _createTaskReference($fileId, $brokerTaskId, $taskName) {
|
||||||
$trackId = $this->createTrackReference($fileId);
|
$trackReferenceId = $this->createTrackReference($fileId);
|
||||||
$task = new CeleryTasks();
|
$task = new CeleryTasks();
|
||||||
$task->setDbTaskId($brokerTaskId);
|
$task->setDbTaskId($brokerTaskId);
|
||||||
$task->setDbName($taskName);
|
$task->setDbName($taskName);
|
||||||
$utc = new DateTimeZone("UTC");
|
$utc = new DateTimeZone("UTC");
|
||||||
$task->setDbDispatchTime(new DateTime("now", $utc));
|
$task->setDbDispatchTime(new DateTime("now", $utc));
|
||||||
$task->setDbStatus(CELERY_PENDING_STATUS);
|
$task->setDbStatus(CELERY_PENDING_STATUS);
|
||||||
$task->setDbTrackReference($trackId);
|
$task->setDbTrackReference($trackReferenceId);
|
||||||
$task->save();
|
$task->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a CeleryTasks object for a completed upload
|
* Update a CeleryTasks object for a completed task
|
||||||
* TODO: should we have a database layer class to handle Propel operations?
|
* TODO: should we have a database layer class to handle Propel operations?
|
||||||
*
|
*
|
||||||
* @param $trackId int ThirdPartyTrackReferences identifier
|
* @param $trackId int ThirdPartyTrackReferences identifier
|
||||||
|
|
|
@ -54,7 +54,7 @@ abstract class ThirdPartyService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a ThirdPartyTrackReferences from the database.
|
* Remove a ThirdPartyTrackReferences row from the database.
|
||||||
* This is necessary if the track was removed from the service
|
* This is necessary if the track was removed from the service
|
||||||
* or the foreign id in our database is incorrect
|
* or the foreign id in our database is incorrect
|
||||||
*
|
*
|
||||||
|
|
|
@ -481,6 +481,14 @@ li.ui-state-default {
|
||||||
overflow-x: hidden; /* Show the y-direction scrollbar (magic!) */
|
overflow-x: hidden; /* Show the y-direction scrollbar (magic!) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-name {
|
||||||
|
float: left;
|
||||||
|
max-width: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
.inner_editor_wrapper {
|
.inner_editor_wrapper {
|
||||||
max-height: 60%;
|
max-height: 60%;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
|
@ -289,3 +289,18 @@ function getUsabilityHint() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupTextScrolling(parent, selector) {
|
||||||
|
parent.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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
parent.on("mouseleave", selector, function () {
|
||||||
|
$(this).stop().animate({
|
||||||
|
textIndent: "0"
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
}
|
|
@ -76,35 +76,35 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
mod.placeholder = function(mediaType) {
|
mod.placeholder = function(mediaType) {
|
||||||
switch (mediaType) {
|
switch (mediaType) {
|
||||||
// TODO: remove duplication in a nice way?
|
// TODO: remove duplication in a nice way?
|
||||||
case MediaTypeEnum.FILE:
|
case mod.MediaTypeEnum.FILE:
|
||||||
return {
|
return {
|
||||||
"media": "tracks",
|
"media": "tracks",
|
||||||
"icon": "icon-music",
|
"icon": "icon-music",
|
||||||
"subtext": "Click 'Upload' to add some now.",
|
"subtext": "Click 'Upload' to add some now.",
|
||||||
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/add-media/"
|
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/add-media/"
|
||||||
};
|
};
|
||||||
case MediaTypeEnum.PLAYLIST:
|
case mod.MediaTypeEnum.PLAYLIST:
|
||||||
return {
|
return {
|
||||||
"media": "playlists",
|
"media": "playlists",
|
||||||
"icon": "icon-list",
|
"icon": "icon-list",
|
||||||
"subtext": "Click 'New' to create one now.",
|
"subtext": "Click 'New' to create one now.",
|
||||||
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
|
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
|
||||||
};
|
};
|
||||||
case MediaTypeEnum.BLOCK:
|
case mod.MediaTypeEnum.BLOCK:
|
||||||
return {
|
return {
|
||||||
"media": "smart blocks",
|
"media": "smart blocks",
|
||||||
"icon": "icon-time",
|
"icon": "icon-time",
|
||||||
"subtext": "Click 'New' to create one now.",
|
"subtext": "Click 'New' to create one now.",
|
||||||
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
|
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
|
||||||
};
|
};
|
||||||
case MediaTypeEnum.WEBSTREAM:
|
case mod.MediaTypeEnum.WEBSTREAM:
|
||||||
return {
|
return {
|
||||||
"media": "webstreams",
|
"media": "webstreams",
|
||||||
"icon": "icon-random",
|
"icon": "icon-random",
|
||||||
"subtext": "Click 'New' to create one now.",
|
"subtext": "Click 'New' to create one now.",
|
||||||
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
|
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
|
||||||
};
|
};
|
||||||
case MediaTypeEnum.PODCAST:
|
case mod.MediaTypeEnum.PODCAST:
|
||||||
return {
|
return {
|
||||||
"media": "podcasts",
|
"media": "podcasts",
|
||||||
"icon": "icon-headphones",
|
"icon": "icon-headphones",
|
||||||
|
@ -448,7 +448,7 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
openTabObjectIds.each(function(i, el) {
|
openTabObjectIds.each(function(i, el) {
|
||||||
var v = parseInt($(el).val());
|
var v = parseInt($(el).val());
|
||||||
if ($.inArray(v, mediaIds) > -1) {
|
if ($.inArray(v, mediaIds) > -1) {
|
||||||
AIRTIME.playlist.closeTab($(el).closest(".pl-content").attr("data-tab-id"));
|
AIRTIME.tabs.closeTab($(el).closest(".pl-content").attr("data-tab-id"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -710,24 +710,6 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
} else if (!aData.is_playlist) {
|
} else if (!aData.is_playlist) {
|
||||||
$(nRow).find("td.library_is_playlist").html('');
|
$(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.
|
// remove any selected nodes before the draw.
|
||||||
"fnPreDrawCallback": function (oSettings) {
|
"fnPreDrawCallback": function (oSettings) {
|
||||||
|
@ -985,6 +967,26 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// add the play function to the library_type td
|
||||||
|
$libTable.on("click", "td.library_type", function () {
|
||||||
|
var aData = $(this).parent().data().aData;
|
||||||
|
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
$libTable.find("tbody").on("mousedown", "tr[class*='lib'] > td:not(.library_checkbox, .dataTables_empty)", function(ev) {
|
$libTable.find("tbody").on("mousedown", "tr[class*='lib'] > td:not(.library_checkbox, .dataTables_empty)", function(ev) {
|
||||||
var $tr = $(this).parent(),
|
var $tr = $(this).parent(),
|
||||||
// Get the ID of the selected row
|
// Get the ID of the selected row
|
||||||
|
|
|
@ -157,27 +157,12 @@ $(document).ready(function () {
|
||||||
getUsabilityHint();
|
getUsabilityHint();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
|
||||||
"fnCreatedRow": function(nRow) {
|
|
||||||
$(nRow).find("td").hover(
|
|
||||||
function () {
|
|
||||||
var sw = $(this)[0].scrollWidth, iw = $(this).innerWidth();
|
|
||||||
if (sw > iw) {
|
|
||||||
$(this).stop().animate({
|
|
||||||
textIndent: "-" + (sw - iw) + "px"
|
|
||||||
}, sw * 8);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function () {
|
|
||||||
$(this).stop().animate({
|
|
||||||
textIndent: "0"
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setupTextScrolling($("#recent_uploads"), "td");
|
||||||
|
|
||||||
self.isRecentUploadsRefreshTimerActive = false;
|
self.isRecentUploadsRefreshTimerActive = false;
|
||||||
|
|
||||||
self.startRefreshingRecentUploads = function () {
|
self.startRefreshingRecentUploads = function () {
|
||||||
|
|
|
@ -12,9 +12,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
viewport,
|
viewport,
|
||||||
$lib,
|
$lib,
|
||||||
$pl,
|
$pl,
|
||||||
widgetHeight,
|
widgetHeight;
|
||||||
$tabCount = 0,
|
|
||||||
$openTabs = {};
|
|
||||||
|
|
||||||
function isTimeValid(time) {
|
function isTimeValid(time) {
|
||||||
//var regExpr = new RegExp("^\\d{2}[:]\\d{2}[:]\\d{2}([.]\\d{1,6})?$");
|
//var regExpr = new RegExp("^\\d{2}[:]\\d{2}[:]\\d{2}([.]\\d{1,6})?$");
|
||||||
|
@ -356,17 +354,6 @@ var AIRTIME = (function(AIRTIME){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateActiveTabName(newTabName) {
|
|
||||||
/*
|
|
||||||
var nameElement = $(this);
|
|
||||||
//remove any newlines if user somehow snuck them in (easy to do if dragging/dropping text)
|
|
||||||
nameElement.text(nameElement.text().replace("\n", ""));
|
|
||||||
|
|
||||||
var name = $pl.find(".playlist_name_display").val();
|
|
||||||
*/
|
|
||||||
$(".nav.nav-tabs .active a > span.tab-name").text(newTabName);
|
|
||||||
}
|
|
||||||
|
|
||||||
function redrawLib() {
|
function redrawLib() {
|
||||||
var dt = $lib.find("#library_display").dataTable();
|
var dt = $lib.find("#library_display").dataTable();
|
||||||
|
|
||||||
|
@ -394,7 +381,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
setCueEvents();
|
setCueEvents();
|
||||||
setFadeEvents();
|
setFadeEvents();
|
||||||
mod.setModified(json.modified);
|
mod.setModified(json.modified);
|
||||||
updateActiveTabName(json.name);
|
AIRTIME.tabs.setActiveTabName(json.name);
|
||||||
|
|
||||||
AIRTIME.playlist.validatePlaylistElements();
|
AIRTIME.playlist.validatePlaylistElements();
|
||||||
redrawLib();
|
redrawLib();
|
||||||
|
@ -425,10 +412,10 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$('.zend_form + .spl-no-margin > div:has(*:visible):last').css('margin-left', 0);
|
$('.zend_form + .spl-no-margin > div:has(*:visible):last').css('margin-left', 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getId(pl) {
|
mod.getId = function(pl) {
|
||||||
pl = (pl === undefined) ? $pl : pl;
|
pl = (pl === undefined) ? $pl : pl;
|
||||||
return parseInt(pl.find(".obj_id").val(), 10);
|
return parseInt(pl.find(".obj_id").val(), 10);
|
||||||
}
|
};
|
||||||
|
|
||||||
mod.getModified = function(pl) {
|
mod.getModified = function(pl) {
|
||||||
pl = (pl === undefined) ? $pl : pl;
|
pl = (pl === undefined) ? $pl : pl;
|
||||||
|
@ -443,115 +430,6 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$pl.find(".title_obj_name").text(title);
|
$pl.find(".title_obj_name").text(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTabName(name) {
|
|
||||||
var id = $pl.data("tab-id");
|
|
||||||
$("#show_builder").find("[data-tab-id='" + id + "']").find(".tab-name").text(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Should all be moved to builder.js eventually
|
|
||||||
*/
|
|
||||||
function buildNewTab(json) {
|
|
||||||
AIRTIME.library.selectNone();
|
|
||||||
|
|
||||||
var tabId = $openTabs[json.type + json.id];
|
|
||||||
if (tabId !== undefined) {
|
|
||||||
AIRTIME.showbuilder.switchTab($("#pl-tab-content-" + tabId), $("#pl-tab-" + tabId));
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
$tabCount++;
|
|
||||||
|
|
||||||
var wrapper = "<div data-tab-type='" + json.type + "' data-tab-id='" + $tabCount + "' id='pl-tab-content-" + $tabCount + "' class='side_playlist pl-content'><div class='editor_pane_wrapper'></div></div>",
|
|
||||||
t = $("#show_builder").append(wrapper).find("#pl-tab-content-" + $tabCount),
|
|
||||||
pane = $(".editor_pane_wrapper:last"),
|
|
||||||
name = json.type == "md" ? // file
|
|
||||||
pane.append(json.html).find("#track_title").val() + $.i18n._(" - Metadata Editor")
|
|
||||||
: pane.append(json.html).find(".playlist_name_display").val(),
|
|
||||||
tab =
|
|
||||||
"<li data-tab-id='" + $tabCount + "' data-tab-type='" + json.type + "' id='pl-tab-" + $tabCount + "' role='presentation' class='active'>" +
|
|
||||||
"<a href='javascript:void(0)'><span class='tab-name'></span>" +
|
|
||||||
"<span href='#' class='lib_pl_close icon-remove'></span>" +
|
|
||||||
"</a>" +
|
|
||||||
"</li>",
|
|
||||||
tabs = $(".nav.nav-tabs");
|
|
||||||
|
|
||||||
if (json.id) {
|
|
||||||
$openTabs[json.type + json.id] = $tabCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
$(".nav.nav-tabs li").removeClass("active");
|
|
||||||
tabs.append(tab);
|
|
||||||
tabs.find("#pl-tab-" + $tabCount + " span.tab-name").text(name);
|
|
||||||
|
|
||||||
var newTab = $("#pl-tab-" + $tabCount);
|
|
||||||
AIRTIME.showbuilder.switchTab(t, newTab);
|
|
||||||
|
|
||||||
return {wrapper: pane, tab: newTab, pane: t};
|
|
||||||
}
|
|
||||||
|
|
||||||
function openFileMdEditor(json) {
|
|
||||||
var newTab = buildNewTab(json);
|
|
||||||
if (newTab === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
initFileMdEvents(newTab);
|
|
||||||
initialEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initFileMdEvents(newTab) {
|
|
||||||
newTab.tab.on("click", function() {
|
|
||||||
if (!$(this).hasClass('active')) {
|
|
||||||
AIRTIME.showbuilder.switchTab(newTab.pane, newTab.tab);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
newTab.wrapper.find(".md-cancel").on("click", function() {
|
|
||||||
closeTab();
|
|
||||||
});
|
|
||||||
|
|
||||||
newTab.wrapper.find(".md-save").on("click", function() {
|
|
||||||
var file_id = newTab.wrapper.find('#file_id').val(),
|
|
||||||
data = newTab.wrapper.find("#edit-md-dialog form").serializeArray();
|
|
||||||
$.post(baseUrl+'library/edit-file-md', {format: "json", id: file_id, data: data}, function() {
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AIRTIME.playlist.closeTab();
|
|
||||||
});
|
|
||||||
|
|
||||||
newTab.wrapper.find('#edit-md-dialog').on("keyup", function(event) {
|
|
||||||
if (event.keyCode === 13) {
|
|
||||||
newTab.wrapper.find('.md-save').click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function openPlaylist(json) {
|
|
||||||
var newTab = buildNewTab(json);
|
|
||||||
if (newTab === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
newTab.tab.on("click", function() {
|
|
||||||
if (!$(this).hasClass('active')) {
|
|
||||||
AIRTIME.showbuilder.switchTab(newTab.pane, newTab.tab);
|
|
||||||
$.post(baseUrl+'playlist/edit',
|
|
||||||
{format: "json", id: newTab.pane.find(".obj_id").val(), type: newTab.pane.find(".obj_type").val()});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
AIRTIME.playlist.init();
|
|
||||||
|
|
||||||
// functions in smart_blockbuilder.js
|
|
||||||
setupUI();
|
|
||||||
appendAddButton();
|
|
||||||
appendModAddButton();
|
|
||||||
removeButtonCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
function openPlaylistPanel() {
|
function openPlaylistPanel() {
|
||||||
viewport = AIRTIME.utilities.findViewportDimensions();
|
viewport = AIRTIME.utilities.findViewportDimensions();
|
||||||
var screenWidth = Math.floor(viewport.width - 40);
|
var screenWidth = Math.floor(viewport.width - 40);
|
||||||
|
@ -562,33 +440,6 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$("#pl_edit").hide();
|
$("#pl_edit").hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeTab(id) {
|
|
||||||
var curr = $(".active-tab"),
|
|
||||||
pane = id ? $(".pl-content[data-tab-id='" + id + "']") : curr,
|
|
||||||
tab = id ? $(".nav.nav-tabs [data-tab-id='" + id + "']") : $(".nav.nav-tabs .active"),
|
|
||||||
toPane = pane.next().length > 0 ? pane.next() : pane.prev(),
|
|
||||||
toTab = tab.next().length > 0 ? tab.next() : tab.prev(),
|
|
||||||
objId = pane.find(".obj_id").val(),
|
|
||||||
pl = id ? pane : $pl;
|
|
||||||
delete $openTabs[tab.attr("data-tab-type") + objId]; // Remove the closed tab from our open tabs array
|
|
||||||
|
|
||||||
// Remove the relevant DOM elements (the tab and the tab content)
|
|
||||||
tab.remove();
|
|
||||||
pl.remove();
|
|
||||||
|
|
||||||
if (pane.get(0) == curr.get(0)) { // Closing the current tab, otherwise we don't need to switch tabs
|
|
||||||
AIRTIME.showbuilder.switchTab(toPane, toTab);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we close a tab that was causing tabs to wrap to the next row, we need to resize to change the
|
|
||||||
// margin for the tab nav
|
|
||||||
AIRTIME.playlist.onResize();
|
|
||||||
}
|
|
||||||
|
|
||||||
mod.closeTab = function(id) {
|
|
||||||
closeTab(id);
|
|
||||||
};
|
|
||||||
|
|
||||||
//Purpose of this function is to iterate over all playlist elements
|
//Purpose of this function is to iterate over all playlist elements
|
||||||
//and verify whether they can be previewed by the browser or not. If not
|
//and verify whether they can be previewed by the browser or not. If not
|
||||||
//then the playlist element is greyed out
|
//then the playlist element is greyed out
|
||||||
|
@ -937,7 +788,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
setTimeout(function(){$status.fadeOut("slow", function(){$status.empty()})}, 5000);
|
setTimeout(function(){$status.fadeOut("slow", function(){$status.empty()})}, 5000);
|
||||||
|
|
||||||
$pl.find(".title_obj_name").val(name);
|
$pl.find(".title_obj_name").val(name);
|
||||||
updateActiveTabName(name);
|
AIRTIME.tabs.setActiveTabName(name);
|
||||||
|
|
||||||
var $ws_id = $(".active-tab .obj_id");
|
var $ws_id = $(".active-tab .obj_id");
|
||||||
$ws_id.attr("value", json.streamId);
|
$ws_id.attr("value", json.streamId);
|
||||||
|
@ -985,26 +836,21 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$(this).unbind("click"); // Prevent repeated clicks in quick succession from closing multiple tabs
|
$(this).unbind("click"); // Prevent repeated clicks in quick succession from closing multiple tabs
|
||||||
|
|
||||||
var tabId = $(this).closest("li").attr("data-tab-id");
|
var tabId = $(this).closest("li").attr("data-tab-id");
|
||||||
//AIRTIME.showbuilder.switchTab($("#pl-tab-content-" + tabId), $("#pl-tab-" + tabId));
|
|
||||||
//$pl.hide();
|
|
||||||
|
|
||||||
// We need to update the text on the add button
|
// We need to update the text on the add button
|
||||||
AIRTIME.library.checkAddButton();
|
AIRTIME.library.checkAddButton();
|
||||||
// We also need to run the draw callback to update how dragged items are drawn
|
// We also need to run the draw callback to update how dragged items are drawn
|
||||||
AIRTIME.library.fnDrawCallback();
|
AIRTIME.library.fnDrawCallback();
|
||||||
|
|
||||||
var playlistNameElem = $pl.siblings("[data-tab-id='" + tabId + "']").find('.playlist_name_display');
|
var playlistNameElem = AIRTIME.tabs.get(tabId).find('.tab-name');
|
||||||
var name = "";
|
var name = playlistNameElem.text().trim();
|
||||||
if (playlistNameElem.val() !== undefined) {
|
|
||||||
name = playlistNameElem.val().trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((name == $.i18n._("Untitled Playlist")
|
if ((name == $.i18n._("Untitled Playlist")
|
||||||
|| name == $.i18n._("Untitled Smart Block"))
|
|| name == $.i18n._("Untitled Smart Block"))
|
||||||
&& $pl.find(".spl_sortable .spl_empty").length == 1) {
|
&& $pl.find(".spl_sortable .spl_empty").length == 1) {
|
||||||
mod.fnDelete(undefined, tabId);
|
mod.fnDelete(undefined, tabId);
|
||||||
} else {
|
} else {
|
||||||
closeTab(tabId);
|
AIRTIME.tabs.closeTab(tabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax( {
|
$.ajax( {
|
||||||
|
@ -1041,7 +887,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
setTitleLabel(json.name);
|
setTitleLabel(json.name);
|
||||||
setTabName(json.name);
|
AIRTIME.tabs.setActiveTabName(json.name);
|
||||||
mod.setModified(json.modified);
|
mod.setModified(json.modified);
|
||||||
|
|
||||||
if (obj_type == "block") {
|
if (obj_type == "block") {
|
||||||
|
@ -1176,7 +1022,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$.post(url,
|
$.post(url,
|
||||||
{format: "json", type: 'playlist'},
|
{format: "json", type: 'playlist'},
|
||||||
function(json){
|
function(json){
|
||||||
openPlaylist(json);
|
AIRTIME.tabs.openPlaylistTab(json);
|
||||||
redrawLib();
|
redrawLib();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1189,7 +1035,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$.post(url,
|
$.post(url,
|
||||||
{format: "json"},
|
{format: "json"},
|
||||||
function(json){
|
function(json){
|
||||||
openPlaylist(json);
|
AIRTIME.tabs.openPlaylistTab(json);
|
||||||
redrawLib();
|
redrawLib();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1203,13 +1049,13 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$.post(url,
|
$.post(url,
|
||||||
{format: "json", type: 'block'},
|
{format: "json", type: 'block'},
|
||||||
function(json){
|
function(json){
|
||||||
openPlaylist(json);
|
AIRTIME.tabs.openPlaylistTab(json);
|
||||||
redrawLib();
|
redrawLib();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.fileMdEdit = function(json) {
|
mod.fileMdEdit = function(json) {
|
||||||
openFileMdEditor(json);
|
AIRTIME.tabs.openFileMdEditorTab(json);
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.fnEdit = function(id, type, url) {
|
mod.fnEdit = function(id, type, url) {
|
||||||
|
@ -1219,7 +1065,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$.post(url,
|
$.post(url,
|
||||||
{format: "json", id: id, type: type},
|
{format: "json", id: id, type: type},
|
||||||
function(json){
|
function(json){
|
||||||
openPlaylist(json);
|
AIRTIME.tabs.openPlaylistTab(json);
|
||||||
redrawLib();
|
redrawLib();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1229,7 +1075,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
var url, id, lastMod, type, pl = (tabId === undefined) ? $pl : $('#pl-tab-content-' + tabId);
|
var url, id, lastMod, type, pl = (tabId === undefined) ? $pl : $('#pl-tab-content-' + tabId);
|
||||||
|
|
||||||
stopAudioPreview();
|
stopAudioPreview();
|
||||||
id = (plid === undefined) ? getId(pl) : plid;
|
id = (plid === undefined) ? mod.getId(pl) : plid;
|
||||||
lastMod = mod.getModified(pl);
|
lastMod = mod.getModified(pl);
|
||||||
type = pl.find('.obj_type').val();
|
type = pl.find('.obj_type').val();
|
||||||
url = baseUrl+'playlist/delete';
|
url = baseUrl+'playlist/delete';
|
||||||
|
@ -1237,7 +1083,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$.post(url,
|
$.post(url,
|
||||||
{format: "json", ids: id, modified: lastMod, type: type},
|
{format: "json", ids: id, modified: lastMod, type: type},
|
||||||
function(json) {
|
function(json) {
|
||||||
closeTab(tabId);
|
AIRTIME.tabs.closeTab(tabId);
|
||||||
redrawLib();
|
redrawLib();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1246,7 +1092,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
var url, id, lastMod;
|
var url, id, lastMod;
|
||||||
|
|
||||||
stopAudioPreview();
|
stopAudioPreview();
|
||||||
id = (wsid === undefined) ? getId() : wsid;
|
id = (wsid === undefined) ? mod.getId() : wsid;
|
||||||
lastMod = mod.getModified();
|
lastMod = mod.getModified();
|
||||||
type = $pl.find('.obj_type').val();
|
type = $pl.find('.obj_type').val();
|
||||||
url = baseUrl+'webstream/delete';
|
url = baseUrl+'webstream/delete';
|
||||||
|
@ -1254,7 +1100,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
$.post(url,
|
$.post(url,
|
||||||
{format: "json", ids: id, modified: lastMod, type: type},
|
{format: "json", ids: id, modified: lastMod, type: type},
|
||||||
function(json){
|
function(json){
|
||||||
openPlaylist(json);
|
AIRTIME.tabs.openPlaylistTab(json);
|
||||||
redrawLib();
|
redrawLib();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1275,7 +1121,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.fnOpenPlaylist = function(json) {
|
mod.fnOpenPlaylist = function(json) {
|
||||||
openPlaylist(json);
|
AIRTIME.tabs.openPlaylistTab(json);
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.enableUI = function() {
|
mod.enableUI = function() {
|
||||||
|
@ -1305,7 +1151,7 @@ var AIRTIME = (function(AIRTIME){
|
||||||
|
|
||||||
mod.replaceForm = function(json){
|
mod.replaceForm = function(json){
|
||||||
$pl.find('.editor_pane_wrapper').html(json.html);
|
$pl.find('.editor_pane_wrapper').html(json.html);
|
||||||
openPlaylist(json);
|
AIRTIME.tabs.openPlaylistTab(json);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1576,21 +1422,17 @@ var AIRTIME = (function(AIRTIME){
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.setAsActive = function() {
|
mod.setupEventListeners = function() {
|
||||||
$pl = $(".active-tab");
|
initialEvents();
|
||||||
$.post(baseUrl + "playlist/change-playlist", {"id": getId(), "type": $pl.find('.obj_type').val()});
|
};
|
||||||
|
|
||||||
|
mod.setCurrent = function(pl) {
|
||||||
|
$pl = pl;
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.init = function() {
|
mod.init = function() {
|
||||||
AIRTIME.playlist.setAsActive();
|
AIRTIME.tabs.updateActiveTab();
|
||||||
|
if (!$pl) return;
|
||||||
//$pl.delegate("#spl_delete", {"click": function(ev){
|
|
||||||
// AIRTIME.playlist.fnDelete();
|
|
||||||
//}});
|
|
||||||
//
|
|
||||||
//$pl.delegate("#ws_delete", {"click": function(ev){
|
|
||||||
// AIRTIME.playlist.fnWsDelete();
|
|
||||||
//}});
|
|
||||||
|
|
||||||
$pl.delegate(".pl-waveform-cues-btn", {"click": function(ev){
|
$pl.delegate(".pl-waveform-cues-btn", {"click": function(ev){
|
||||||
AIRTIME.playlist.showCuesWaveform(ev);
|
AIRTIME.playlist.showCuesWaveform(ev);
|
||||||
|
|
|
@ -108,21 +108,6 @@ var AIRTIME = (function(AIRTIME){
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.switchTab = function(tab, el) {
|
|
||||||
$(".active-tab").hide().removeClass("active-tab");
|
|
||||||
tab.addClass("active-tab").show();
|
|
||||||
|
|
||||||
$(".nav.nav-tabs .active").removeClass("active");
|
|
||||||
el.addClass("active");
|
|
||||||
|
|
||||||
if (tab.hasClass("pl-content")) {
|
|
||||||
AIRTIME.playlist.setAsActive();
|
|
||||||
}
|
|
||||||
AIRTIME.playlist.onResize();
|
|
||||||
AIRTIME.library.fnRedraw();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
mod.checkSelectButton = function() {
|
mod.checkSelectButton = function() {
|
||||||
var $selectable = $sbTable.find("tr");
|
var $selectable = $sbTable.find("tr");
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ AIRTIME = (function(AIRTIME) {
|
||||||
|
|
||||||
$("#schedule-tab").on("click", function() {
|
$("#schedule-tab").on("click", function() {
|
||||||
if (!$(this).hasClass('active')) {
|
if (!$(this).hasClass('active')) {
|
||||||
AIRTIME.showbuilder.switchTab($("#show_builder .outer-datatable-wrapper"), $(this));
|
AIRTIME.tabs.switchTab($("#show_builder .outer-datatable-wrapper"), $(this));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
var AIRTIME = (function(AIRTIME){
|
||||||
|
var mod,
|
||||||
|
$tabCount = 0,
|
||||||
|
$openTabs = {},
|
||||||
|
$activeTab,
|
||||||
|
$activeTabPane;
|
||||||
|
|
||||||
|
if (AIRTIME.tabs === undefined) {
|
||||||
|
AIRTIME.tabs = {};
|
||||||
|
}
|
||||||
|
mod = AIRTIME.tabs;
|
||||||
|
|
||||||
|
/* #####################################################
|
||||||
|
Internal Functions
|
||||||
|
##################################################### */
|
||||||
|
|
||||||
|
function buildNewTab(json) {
|
||||||
|
AIRTIME.library.selectNone();
|
||||||
|
|
||||||
|
var tabId = $openTabs[json.type + json.id];
|
||||||
|
if (tabId !== undefined) {
|
||||||
|
mod.switchTab($("#pl-tab-content-" + tabId), $("#pl-tab-" + tabId));
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
$tabCount++;
|
||||||
|
|
||||||
|
var wrapper = "<div data-tab-type='" + json.type + "' data-tab-id='" + $tabCount + "' id='pl-tab-content-" + $tabCount + "' class='side_playlist pl-content'><div class='editor_pane_wrapper'></div></div>",
|
||||||
|
t = $("#show_builder").append(wrapper).find("#pl-tab-content-" + $tabCount),
|
||||||
|
pane = $(".editor_pane_wrapper:last"),
|
||||||
|
name = json.type == "md" ? // file
|
||||||
|
pane.append(json.html).find("#track_title").val() + $.i18n._(" - Metadata Editor")
|
||||||
|
: pane.append(json.html).find(".playlist_name_display").val(),
|
||||||
|
tab =
|
||||||
|
"<li data-tab-id='" + $tabCount + "' data-tab-type='" + json.type + "' id='pl-tab-" + $tabCount + "' role='presentation' class='active'>" +
|
||||||
|
"<a href='javascript:void(0)'><span class='tab-name'></span>" +
|
||||||
|
"<span href='#' class='lib_pl_close icon-remove'></span>" +
|
||||||
|
"</a>" +
|
||||||
|
"</li>",
|
||||||
|
tabs = $(".nav.nav-tabs");
|
||||||
|
|
||||||
|
if (json.id) {
|
||||||
|
$openTabs[json.type + json.id] = $tabCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".nav.nav-tabs li").removeClass("active");
|
||||||
|
tabs.append(tab);
|
||||||
|
tabs.find("#pl-tab-" + $tabCount + " span.tab-name").text(name);
|
||||||
|
|
||||||
|
var newTab = $("#pl-tab-" + $tabCount);
|
||||||
|
mod.switchTab(t, newTab);
|
||||||
|
|
||||||
|
return {wrapper: pane, tab: newTab, pane: t};
|
||||||
|
}
|
||||||
|
|
||||||
|
function initFileMdEvents(newTab) {
|
||||||
|
newTab.tab.on("click", function() {
|
||||||
|
if (!$(this).hasClass('active')) {
|
||||||
|
mod.switchTab(newTab.pane, newTab.tab);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newTab.wrapper.find(".md-cancel").on("click", function() {
|
||||||
|
mod.closeTab();
|
||||||
|
});
|
||||||
|
|
||||||
|
newTab.wrapper.find(".md-save").on("click", function() {
|
||||||
|
var file_id = newTab.wrapper.find('#file_id').val(),
|
||||||
|
data = newTab.wrapper.find("#edit-md-dialog form").serializeArray();
|
||||||
|
$.post(baseUrl+'library/edit-file-md', {format: "json", id: file_id, data: data}, function() {
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mod.closeTab();
|
||||||
|
});
|
||||||
|
|
||||||
|
newTab.wrapper.find('#edit-md-dialog').on("keyup", function(event) {
|
||||||
|
if (event.keyCode === 13) {
|
||||||
|
newTab.wrapper.find('.md-save').click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #####################################################
|
||||||
|
External Functions
|
||||||
|
##################################################### */
|
||||||
|
|
||||||
|
mod.openFileMdEditorTab = function(json) {
|
||||||
|
var newTab = buildNewTab(json);
|
||||||
|
if (newTab === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
initFileMdEvents(newTab);
|
||||||
|
AIRTIME.playlist.setupEventListeners();
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.openPlaylistTab = function(json) {
|
||||||
|
var newTab = buildNewTab(json);
|
||||||
|
if (newTab === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newTab.tab.on("click", function() {
|
||||||
|
if (!$(this).hasClass('active')) {
|
||||||
|
mod.switchTab(newTab.pane, newTab.tab);
|
||||||
|
$.post(baseUrl+'playlist/edit', {
|
||||||
|
format: "json",
|
||||||
|
id: newTab.pane.find(".obj_id").val(),
|
||||||
|
type: newTab.pane.find(".obj_type").val()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AIRTIME.playlist.init();
|
||||||
|
|
||||||
|
// functions in smart_blockbuilder.js
|
||||||
|
setupUI();
|
||||||
|
appendAddButton();
|
||||||
|
appendModAddButton();
|
||||||
|
removeButtonCheck();
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.closeTab = function(id) {
|
||||||
|
var pane = id ? mod.get(id, true) : $activeTabPane,
|
||||||
|
tab = id ? mod.get(id) : $activeTab,
|
||||||
|
toPane = pane.next().length > 0 ? pane.next() : pane.prev(),
|
||||||
|
toTab = tab.next().length > 0 ? tab.next() : tab.prev(),
|
||||||
|
objId = pane.find(".obj_id").val(),
|
||||||
|
contents = id ? pane : $activeTabPane;
|
||||||
|
delete $openTabs[tab.data("tab-type") + objId]; // Remove the closed tab from our open tabs array
|
||||||
|
|
||||||
|
// Remove the relevant DOM elements (the tab and the tab content)
|
||||||
|
tab.remove();
|
||||||
|
contents.remove();
|
||||||
|
|
||||||
|
if (pane.get(0) == $activeTabPane.get(0)) { // Closing the current tab, otherwise we don't need to switch tabs
|
||||||
|
mod.switchTab(toPane, toTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we close a tab that was causing tabs to wrap to the next row, we need to resize to change the
|
||||||
|
// margin for the tab nav
|
||||||
|
AIRTIME.playlist.onResize();
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.switchTab = function(tabPane, tab) {
|
||||||
|
$activeTabPane.hide().removeClass("active-tab");
|
||||||
|
tabPane.addClass("active-tab").show();
|
||||||
|
|
||||||
|
$activeTab.removeClass("active");
|
||||||
|
tab.addClass("active");
|
||||||
|
|
||||||
|
mod.updateActiveTab();
|
||||||
|
|
||||||
|
AIRTIME.playlist.onResize();
|
||||||
|
AIRTIME.library.fnRedraw();
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.setActiveTabName = function(name) {
|
||||||
|
$activeTab.find(".tab-name").text(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.updateActiveTab = function() {
|
||||||
|
$activeTabPane = $(".active-tab");
|
||||||
|
$activeTab = $(".nav.nav-tabs .active");
|
||||||
|
if ($activeTabPane.hasClass("pl-content")) {
|
||||||
|
mod.updatePlaylist();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.updatePlaylist = function() {
|
||||||
|
AIRTIME.playlist.setCurrent($activeTabPane);
|
||||||
|
$.post(baseUrl + "playlist/change-playlist", {
|
||||||
|
"id": AIRTIME.playlist.getId($activeTabPane),
|
||||||
|
"type": $activeTabPane.find('.obj_type').val()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.getActiveTab = function() {
|
||||||
|
return $activeTabPane;
|
||||||
|
};
|
||||||
|
|
||||||
|
mod.get = function(id, getContents) {
|
||||||
|
var allTabs = getContents ? $(".pl-content") : $(".nav.nav-tabs li");
|
||||||
|
if (id) {
|
||||||
|
var t = null;
|
||||||
|
allTabs.each(function() {
|
||||||
|
if ($(this).data("tab-id") == id) {
|
||||||
|
t = $(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// An id was passed in, but no tab with that id exists
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return allTabs;
|
||||||
|
};
|
||||||
|
|
||||||
|
return AIRTIME;
|
||||||
|
|
||||||
|
}(AIRTIME || {}));
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
setupTextScrolling($("#show_builder"), ".tab-name");
|
||||||
|
});
|
Loading…
Reference in New Issue