SAAS-1165 - implement most functionality for left-hand podcast episodes view
This commit is contained in:
parent
a984cee13a
commit
0be26d621b
11 changed files with 375 additions and 150 deletions
|
@ -64,7 +64,7 @@ class PodcastManager {
|
||||||
// episodes in the list of episodes to ingest, don't skip this episode - we should try to ingest the
|
// episodes in the list of episodes to ingest, don't skip this episode - we should try to ingest the
|
||||||
// most recent episode when the user first sets the podcast to automatic ingest.
|
// most recent episode when the user first sets the podcast to automatic ingest.
|
||||||
// If the publication date of this episode is before the ingest timestamp, we don't need to ingest it
|
// If the publication date of this episode is before the ingest timestamp, we don't need to ingest it
|
||||||
if ((empty($ts) && !empty($episodes)) || strtotime($episodeData["pub_date"]) < strtotime($ts)) {
|
if ((empty($ts) && ($i > 0)) || strtotime($episodeData["pub_date"]) < strtotime($ts)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$episode = PodcastEpisodesQuery::create()->findOneByDbEpisodeGuid($episodeData["guid"]);
|
$episode = PodcastEpisodesQuery::create()->findOneByDbEpisodeGuid($episodeData["guid"]);
|
||||||
|
|
|
@ -222,6 +222,7 @@ class LibraryController extends Zend_Controller_Action
|
||||||
$message = null;
|
$message = null;
|
||||||
$noPermissionMsg = _("You don't have permission to delete selected items.");
|
$noPermissionMsg = _("You don't have permission to delete selected items.");
|
||||||
|
|
||||||
|
Logging::info($mediaItems);
|
||||||
foreach ($mediaItems as $media) {
|
foreach ($mediaItems as $media) {
|
||||||
|
|
||||||
if ($media["type"] === "audioclip") {
|
if ($media["type"] === "audioclip") {
|
||||||
|
|
|
@ -267,16 +267,23 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir
|
||||||
public function _getImportedPodcastEpisodeArray($podcast, $episodes) {
|
public function _getImportedPodcastEpisodeArray($podcast, $episodes) {
|
||||||
$rss = Application_Service_PodcastService::getPodcastFeed($podcast->getDbUrl());
|
$rss = Application_Service_PodcastService::getPodcastFeed($podcast->getDbUrl());
|
||||||
$episodeIds = array();
|
$episodeIds = array();
|
||||||
|
$episodeFiles = array();
|
||||||
foreach ($episodes as $e) {
|
foreach ($episodes as $e) {
|
||||||
array_push($episodeIds, $e->getDbEpisodeGuid());
|
array_push($episodeIds, $e->getDbEpisodeGuid());
|
||||||
|
$episodeFiles[$e->getDbEpisodeGuid()] = $e->getDbFileId();
|
||||||
}
|
}
|
||||||
|
|
||||||
$episodesArray = array();
|
$episodesArray = array();
|
||||||
foreach ($rss->get_items() as $item) {
|
foreach ($rss->get_items() as $item) {
|
||||||
|
$itemId = $item->get_id();
|
||||||
|
$ingested = in_array($itemId, $episodeIds) ? (empty($episodeFiles[$itemId]) ? -1 : 1) : 0;
|
||||||
|
$file = $ingested > 0 && !empty($episodeFiles[$itemId]) ?
|
||||||
|
CcFiles::getSanitizedFileById($episodeFiles[$itemId]) : array();
|
||||||
/** @var SimplePie_Item $item */
|
/** @var SimplePie_Item $item */
|
||||||
array_push($episodesArray, array(
|
array_push($episodesArray, array(
|
||||||
"guid" => $item->get_id(),
|
"podcast_id" => $podcast->getDbId(),
|
||||||
"ingested" => in_array($item->get_id(), $episodeIds),
|
"guid" => $itemId,
|
||||||
|
"ingested" => $ingested,
|
||||||
"title" => $item->get_title(),
|
"title" => $item->get_title(),
|
||||||
// From the RSS spec best practices:
|
// From the RSS spec best practices:
|
||||||
// 'An item's author element provides the e-mail address of the person who wrote the item'
|
// 'An item's author element provides the e-mail address of the person who wrote the item'
|
||||||
|
@ -284,7 +291,8 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir
|
||||||
"description" => $item->get_description(),
|
"description" => $item->get_description(),
|
||||||
"pub_date" => $item->get_gmdate(),
|
"pub_date" => $item->get_gmdate(),
|
||||||
"link" => $item->get_link(),
|
"link" => $item->get_link(),
|
||||||
"enclosure" => $item->get_enclosure()
|
"enclosure" => $item->get_enclosure(),
|
||||||
|
"file" => $file
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
<div class="btn-toolbar clearfix">
|
<div class="btn-toolbar clearfix">
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
<button ng-click="discard()" class="btn" type="button" name="cancel">
|
<button ng-click="discard()" class="btn" type="button" name="cancel">
|
||||||
<?php echo _("Cancel") ?>
|
<?php echo _("Close") ?>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class='btn-group pull-right'>
|
<div class='btn-group pull-right'>
|
||||||
|
|
|
@ -200,7 +200,7 @@ thead th.ui-state-default {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
thead th.ui-state-default:not([class*='checkbox']):not([class*='type']):not([class*='image']) {
|
thead th.ui-state-default:not([class*='checkbox']):not([class*='type']):not([class*='image']):not([class*='imported']) {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-toolbar {
|
.btn-toolbar {
|
||||||
margin: 0;
|
/*margin: 0;*/
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -908,7 +908,7 @@ dl.inline-list dd {
|
||||||
.DataTables_sort_wrapper .ui-icon {
|
.DataTables_sort_wrapper .ui-icon {
|
||||||
display: block;
|
display: block;
|
||||||
float: right;
|
float: right;
|
||||||
margin: 5px 0;
|
margin: 6px 0 0 5px;
|
||||||
}
|
}
|
||||||
.dataTables_type {
|
.dataTables_type {
|
||||||
float:right;
|
float:right;
|
||||||
|
@ -3953,12 +3953,20 @@ li .ui-state-hover {
|
||||||
|
|
||||||
/* Podcasts */
|
/* Podcasts */
|
||||||
|
|
||||||
|
.DataTables_sort_wrapper {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: flex;
|
||||||
|
-webkit-justify-content: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
[id^="podcast_episodes"][id$="_wrapper"] {
|
[id^="podcast_episodes"][id$="_wrapper"] {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
|
||||||
float: left;
|
|
||||||
flex: 1 100%;
|
flex: 1 100%;
|
||||||
margin: 4px 0 !important;
|
/*margin: 4px 0 0 !important;*/
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
|
@ -4029,9 +4037,29 @@ li .ui-state-hover {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.podcast_episodes_imported {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imported-flag {
|
||||||
|
margin-bottom: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-icon {
|
||||||
|
background: url("img/loading.gif") no-repeat center center;
|
||||||
|
min-width: 24px;
|
||||||
|
width: 100%;
|
||||||
|
height: 16px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
/* UI Revamp Video */
|
/* UI Revamp Video */
|
||||||
|
|
||||||
#whatsnew {
|
#whatsnew {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -4087,6 +4115,10 @@ li .ui-state-hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
.publish-sources {
|
.publish-sources {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: -webkit-flex;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,6 +263,40 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod.addToSchedule = function (selected) {
|
||||||
|
console.log(selected);
|
||||||
|
var aMediaIds = [], aSchedIds = [], aData = [];
|
||||||
|
|
||||||
|
$.each(selected, function () {
|
||||||
|
aMediaIds.push({
|
||||||
|
"id": this.id,
|
||||||
|
"type": this.ftype
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// process selected files/playlists.
|
||||||
|
$("#show_builder_table").find("tr.sb-selected").each(function (i, el) {
|
||||||
|
aData.push($(el).data("aData"));
|
||||||
|
});
|
||||||
|
|
||||||
|
// process selected schedule rows to add media after.
|
||||||
|
$.each(aData, function () {
|
||||||
|
aSchedIds.push({
|
||||||
|
"id": this.id,
|
||||||
|
"instance": this.instance,
|
||||||
|
"timestamp": this.timestamp
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (aSchedIds.length == 0) {
|
||||||
|
if (!addToCurrentOrNext(aSchedIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds);
|
||||||
|
};
|
||||||
|
|
||||||
mod.setupLibraryToolbar = function() {
|
mod.setupLibraryToolbar = function() {
|
||||||
var $toolbar = $(".lib-content .fg-toolbar:first");
|
var $toolbar = $(".lib-content .fg-toolbar:first");
|
||||||
|
|
||||||
|
@ -284,45 +318,14 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var selected = AIRTIME.library.getSelectedData(), data, i, length, temp, aMediaIds = [], aSchedIds = [], aData = [];
|
var selected = AIRTIME.library.getSelectedData(), aMediaIds = [];
|
||||||
|
|
||||||
if ($("#show_builder_table").is(":visible")) {
|
if ($("#show_builder_table").is(":visible")) {
|
||||||
for (i = 0, length = selected.length; i < length; i++) {
|
mod.addToSchedule(selected);
|
||||||
data = selected[i];
|
|
||||||
aMediaIds.push({
|
|
||||||
"id": data.id,
|
|
||||||
"type": data.ftype
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// process selected files/playlists.
|
|
||||||
$("#show_builder_table tr.sb-selected").each(function (i, el) {
|
|
||||||
aData.push($(el).data("aData"));
|
|
||||||
});
|
|
||||||
|
|
||||||
// process selected schedule rows to add media
|
|
||||||
// after.
|
|
||||||
for (i = 0, length = aData.length; i < length; i++) {
|
|
||||||
temp = aData[i];
|
|
||||||
aSchedIds.push({
|
|
||||||
"id": temp.id,
|
|
||||||
"instance": temp.instance,
|
|
||||||
"timestamp": temp.timestamp
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aSchedIds.length == 0) {
|
|
||||||
if (!addToCurrentOrNext(aSchedIds)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AIRTIME.showbuilder.fnAdd(aMediaIds, aSchedIds);
|
|
||||||
} else {
|
} else {
|
||||||
for (i = 0, length = selected.length; i < length; i++) {
|
$.each(selected, function () {
|
||||||
data = selected[i];
|
aMediaIds.push([this.id, this.ftype]);
|
||||||
aMediaIds.push([data.id, data.ftype]);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// check if a playlist/block is open before adding items
|
// check if a playlist/block is open before adding items
|
||||||
if ($('.active-tab .obj_type').val() == 'playlist'
|
if ($('.active-tab .obj_type').val() == 'playlist'
|
||||||
|
|
|
@ -476,7 +476,11 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
}
|
}
|
||||||
|
|
||||||
chosenItems = {};
|
chosenItems = {};
|
||||||
|
if (oTable == $datatables[mod.DataTableTypeEnum.PODCAST_EPISODES]) {
|
||||||
|
mod.podcastEpisodeTableWidget.reload();
|
||||||
|
} else {
|
||||||
oTable.fnStandingRedraw();
|
oTable.fnStandingRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
//Re-enable the delete button
|
//Re-enable the delete button
|
||||||
AIRTIME.button.enableButton("btn-group #sb-trash", false);
|
AIRTIME.button.enableButton("btn-group #sb-trash", false);
|
||||||
|
@ -1246,6 +1250,8 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.setCurrentTable = function (table) {
|
mod.setCurrentTable = function (table) {
|
||||||
|
// FIXME: This is hacky...
|
||||||
|
mod.podcastEpisodeDataTable.fnClearTable();
|
||||||
var dt = $datatables[table],
|
var dt = $datatables[table],
|
||||||
wrapper = $(dt).closest(".dataTables_wrapper");
|
wrapper = $(dt).closest(".dataTables_wrapper");
|
||||||
$("#library_content").find(".dataTables_wrapper").hide();
|
$("#library_content").find(".dataTables_wrapper").hide();
|
||||||
|
@ -1264,10 +1270,9 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
var aoColumns = [
|
var aoColumns = [
|
||||||
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "library_title" , "sWidth" : "170px" },
|
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "library_title" , "sWidth" : "170px" },
|
||||||
/* Creator */ { "sTitle" : $.i18n._("Creator") , "mDataProp" : "creator" , "sClass" : "library_creator" , "sWidth" : "160px" },
|
/* Creator */ { "sTitle" : $.i18n._("Creator") , "mDataProp" : "creator" , "sClass" : "library_creator" , "sWidth" : "160px" },
|
||||||
/* Upload Time { "sTitle" : $.i18n._("Uploaded") , "mDataProp" : "utime" , "bVisible" : false , "sClass" : "library_upload_time" , "sWidth" : "155px" }, */
|
|
||||||
/* Website */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "bVisible" : false , "sWidth" : "150px" },
|
/* Website */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "bVisible" : false , "sWidth" : "150px" },
|
||||||
/* Year */ { "sTitle" : $.i18n._("Owner") , "mDataProp" : "owner" , "bVisible" : false , "sWidth" : "60px" },
|
/* Year */ { "sTitle" : $.i18n._("Owner") , "mDataProp" : "owner" , "bVisible" : false , "sWidth" : "60px" },
|
||||||
/* URL */ { "sTitle" : $.i18n._("Feed URL") , "mDataProp" : "url" , "bVisible" : false , "sWidth" : "60px" },
|
/* URL */ { "sTitle" : $.i18n._("Feed URL") , "mDataProp" : "url" , "bVisible" : false , "sWidth" : "60px" }
|
||||||
|
|
||||||
];
|
];
|
||||||
var ajaxSourceURL = baseUrl+"rest/podcast";
|
var ajaxSourceURL = baseUrl+"rest/podcast";
|
||||||
|
@ -1277,6 +1282,21 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
podcastToolbarButtons[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.NEW].eventHandlers.click = AIRTIME.podcast.createUrlDialog;
|
podcastToolbarButtons[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.NEW].eventHandlers.click = AIRTIME.podcast.createUrlDialog;
|
||||||
podcastToolbarButtons[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.EDIT].eventHandlers.click = AIRTIME.podcast.editSelectedPodcasts;
|
podcastToolbarButtons[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.EDIT].eventHandlers.click = AIRTIME.podcast.editSelectedPodcasts;
|
||||||
podcastToolbarButtons[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.DELETE].eventHandlers.click = AIRTIME.podcast.deleteSelectedPodcasts;
|
podcastToolbarButtons[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.DELETE].eventHandlers.click = AIRTIME.podcast.deleteSelectedPodcasts;
|
||||||
|
// TODO: only enable this if user has exactly one podcast selected
|
||||||
|
podcastToolbarButtons["ViewPodcast"] = {
|
||||||
|
title : $.i18n._("View Podcast"),
|
||||||
|
iconClass : "icon-chevron-right",
|
||||||
|
extraBtnClass : "btn-small",
|
||||||
|
elementId : "",
|
||||||
|
eventHandlers : {
|
||||||
|
click: function () {
|
||||||
|
var podcast = mod.podcastTableWidget.getSelectedRows()[0];
|
||||||
|
mod.podcastEpisodeTableWidget.reload(podcast.id);
|
||||||
|
mod.podcastTableWidget._clearSelection();
|
||||||
|
mod.setCurrentTable(mod.DataTableTypeEnum.PODCAST_EPISODES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
// Add a button to view the station podcast
|
// Add a button to view the station podcast
|
||||||
podcastToolbarButtons["StationPodcast"] = {
|
podcastToolbarButtons["StationPodcast"] = {
|
||||||
title : $.i18n._("Station Podcast"),
|
title : $.i18n._("Station Podcast"),
|
||||||
|
@ -1305,6 +1325,7 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
mod.podcastTableWidget.assignDblClickHandler(function () {
|
mod.podcastTableWidget.assignDblClickHandler(function () {
|
||||||
var podcast = mod.podcastDataTable.fnGetData($(this).index());
|
var podcast = mod.podcastDataTable.fnGetData($(this).index());
|
||||||
mod.podcastEpisodeTableWidget.reload(podcast.id);
|
mod.podcastEpisodeTableWidget.reload(podcast.id);
|
||||||
|
mod.podcastTableWidget._clearSelection();
|
||||||
mod.setCurrentTable(mod.DataTableTypeEnum.PODCAST_EPISODES);
|
mod.setCurrentTable(mod.DataTableTypeEnum.PODCAST_EPISODES);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1319,6 +1340,41 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
*/
|
*/
|
||||||
mod._initPodcastEpisodeDatatable = function () {
|
mod._initPodcastEpisodeDatatable = function () {
|
||||||
var buttons = {
|
var buttons = {
|
||||||
|
backBtn: {
|
||||||
|
title : $.i18n._('Back to Podcasts'),
|
||||||
|
iconClass : 'icon-chevron-left',
|
||||||
|
extraBtnClass : 'btn-small',
|
||||||
|
elementId : '',
|
||||||
|
eventHandlers : {
|
||||||
|
click: function (e) {
|
||||||
|
mod.setCurrentTable(mod.DataTableTypeEnum.PODCAST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaults = AIRTIME.widgets.Table.getStandardToolbarButtons();
|
||||||
|
defaults[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.NEW].title = "Import";
|
||||||
|
defaults[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.NEW].eventHandlers.click = function () {
|
||||||
|
var episodes = mod.podcastEpisodeTableWidget.getSelectedRows();
|
||||||
|
AIRTIME.podcast.importSelectedEpisodes(episodes, mod.podcastEpisodeTableWidget);
|
||||||
|
};
|
||||||
|
|
||||||
|
defaults[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.DELETE].eventHandlers.click = function () {
|
||||||
|
var podcastId, data = [], episodes = mod.podcastEpisodeTableWidget.getSelectedRows();
|
||||||
|
$.each(episodes, function () {
|
||||||
|
data.push({id: this.file.id, type: this.file.ftype});
|
||||||
|
});
|
||||||
|
mod.fnDeleteItems(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reassign these because integer keys take precedence in iteration order - we want to order based on insertion
|
||||||
|
defaults = {
|
||||||
|
newBtn : defaults[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.NEW],
|
||||||
|
editBtn: defaults[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.EDIT],
|
||||||
|
delBtn : defaults[AIRTIME.widgets.Table.TOOLBAR_BUTTON_ROLES.DELETE]
|
||||||
|
};
|
||||||
|
|
||||||
|
$.extend(true, buttons, defaults, {
|
||||||
addToScheduleBtn: {
|
addToScheduleBtn: {
|
||||||
// TODO: compatibility with checkAddButton function
|
// TODO: compatibility with checkAddButton function
|
||||||
title : $.i18n._('Add to Schedule'),
|
title : $.i18n._('Add to Schedule'),
|
||||||
|
@ -1326,33 +1382,52 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
extraBtnClass : 'btn-small',
|
extraBtnClass : 'btn-small',
|
||||||
elementId : '',
|
elementId : '',
|
||||||
eventHandlers : {
|
eventHandlers : {
|
||||||
click: function (e) {
|
click: function () {
|
||||||
console.log(mod.podcastEpisodeDataTable.fnGetData($(this).index()));
|
var data = [], selected = mod.podcastEpisodeTableWidget.getSelectedRows();
|
||||||
|
$.each(selected, function () { data.push(this.file); });
|
||||||
|
mod.addToSchedule(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
mod.podcastEpisodeTableWidget = AIRTIME.podcast.initPodcastEpisodeDatatable(
|
mod.podcastEpisodeTableWidget = AIRTIME.podcast.initPodcastEpisodeDatatable(
|
||||||
$("#podcast_episodes_table"),
|
$("#podcast_episodes_table"),
|
||||||
{
|
{
|
||||||
bServerSide : false,
|
|
||||||
sAjaxSource : null,
|
|
||||||
// Initialize the table with empty data so we can defer loading
|
|
||||||
// If we load sequentially there's a delay before the table appears
|
|
||||||
aaData : {},
|
|
||||||
aoColumns : [
|
aoColumns : [
|
||||||
/* GUID */ { "sTitle" : "" , "mDataProp" : "guid" , "sClass" : "podcast_episodes_guid" , "bVisible" : false },
|
/* GUID */ { "sTitle" : "" , "mDataProp" : "guid" , "sClass" : "podcast_episodes_guid" , "bVisible" : false },
|
||||||
|
/* Ingested */ { "sTitle" : $.i18n._("Imported?") , "mDataProp" : "importIcon" , "sClass" : "podcast_episodes_imported" , "sWidth" : "120px" },
|
||||||
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" },
|
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" },
|
||||||
/* Author */ { "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" },
|
/* Author */ { "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" },
|
||||||
/* Description */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" },
|
/* Description */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" },
|
||||||
/* Link */ { "sTitle" : $.i18n._("Link") , "mDataProp" : "link" , "sClass" : "podcast_episodes_link" , "sWidth" : "170px" },
|
/* Link */ { "sTitle" : $.i18n._("Link") , "mDataProp" : "link" , "sClass" : "podcast_episodes_link" , "sWidth" : "170px" },
|
||||||
/* Publication Date */ { "sTitle" : $.i18n._("Publication Date") , "mDataProp" : "pub_date" , "sClass" : "podcast_episodes_pub_date" , "sWidth" : "170px" }
|
/* Publication Date */ { "sTitle" : $.i18n._("Publication Date") , "mDataProp" : "pub_date" , "sClass" : "podcast_episodes_pub_date" , "sWidth" : "170px" }
|
||||||
]
|
],
|
||||||
|
bServerSide : false,
|
||||||
|
sAjaxSource : null,
|
||||||
|
// Initialize the table with empty data so we can defer loading
|
||||||
|
// If we load sequentially there's a delay before the table appears
|
||||||
|
aaData : {},
|
||||||
|
oColVis : {
|
||||||
|
aiExclude: [0, 1, 2]
|
||||||
},
|
},
|
||||||
buttons
|
oColReorder: {
|
||||||
|
iFixedColumns: 3 // Checkbox + imported
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buttons,
|
||||||
|
{ hideIngestCheckboxes: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
mod.podcastEpisodeDataTable = $datatables[mod.DataTableTypeEnum.PODCAST_EPISODES] = mod.podcastEpisodeTableWidget.getDatatable();
|
mod.podcastEpisodeDataTable = $datatables[mod.DataTableTypeEnum.PODCAST_EPISODES] = mod.podcastEpisodeTableWidget.getDatatable();
|
||||||
|
mod.podcastEpisodeTableWidget.assignDblClickHandler(function () {
|
||||||
|
var data = mod.podcastEpisodeDataTable.fnGetData($(this).index());
|
||||||
|
if (data.file.length > 0) {
|
||||||
|
mod.dblClickAdd(data.file, data.file.ftype);
|
||||||
|
} else {
|
||||||
|
AIRTIME.podcast.importSelectedEpisodes([data], mod.podcastEpisodeTableWidget);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.libraryInit = libraryInit;
|
mod.libraryInit = libraryInit;
|
||||||
|
|
|
@ -7,7 +7,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
|
|
||||||
mod = AIRTIME.podcast;
|
mod = AIRTIME.podcast;
|
||||||
|
|
||||||
var endpoint = 'rest/podcast/', PodcastTable, $stationPodcastTab;
|
var endpoint = 'rest/podcast/', PodcastEpisodeTable, $stationPodcastTab;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PodcastController constructor.
|
* PodcastController constructor.
|
||||||
|
@ -59,20 +59,6 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.importEpisodes = function () {
|
|
||||||
var episodes = self.episodeTable.getSelectedRows();
|
|
||||||
// TODO: Should we implement a batch endpoint for this instead?
|
|
||||||
jQuery.each(episodes, function () {
|
|
||||||
$http.post(endpoint + $scope.podcast.id + '/episodes', {
|
|
||||||
csrf_token: $scope.csrf,
|
|
||||||
episode: this
|
|
||||||
}).success(function () {
|
|
||||||
self.reloadEpisodeTable();
|
|
||||||
self.episodeTable.getDatatable().fnDraw();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the tab and discard any changes made to the podcast data.
|
* Close the tab and discard any changes made to the podcast data.
|
||||||
*/
|
*/
|
||||||
|
@ -122,7 +108,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
elementId : '',
|
elementId : '',
|
||||||
eventHandlers : {
|
eventHandlers : {
|
||||||
click: function () {
|
click: function () {
|
||||||
$scope.importEpisodes();
|
mod.importSelectedEpisodes(self.episodeTable.getSelectedRows(), self.episodeTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +116,11 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
self.episodeTable = AIRTIME.podcast.initPodcastEpisodeDatatable(
|
self.episodeTable = AIRTIME.podcast.initPodcastEpisodeDatatable(
|
||||||
$scope.tab.contents.find('.podcast_episodes'),
|
$scope.tab.contents.find('.podcast_episodes'),
|
||||||
params,
|
params,
|
||||||
buttons
|
buttons,
|
||||||
|
{
|
||||||
|
hideIngestCheckboxes: true,
|
||||||
|
podcastId: $scope.podcast.id
|
||||||
|
}
|
||||||
);
|
);
|
||||||
self.reloadEpisodeTable();
|
self.reloadEpisodeTable();
|
||||||
};
|
};
|
||||||
|
@ -139,7 +129,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
* Reload the podcast episode table.
|
* Reload the podcast episode table.
|
||||||
*/
|
*/
|
||||||
PodcastController.prototype.reloadEpisodeTable = function() {
|
PodcastController.prototype.reloadEpisodeTable = function() {
|
||||||
this.episodeTable.reload(this.$scope.podcast.id);
|
this.episodeTable.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -166,13 +156,13 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
*/
|
*/
|
||||||
function StationPodcastController($scope, $http, podcast, tab) {
|
function StationPodcastController($scope, $http, podcast, tab) {
|
||||||
// Super call to parent controller
|
// Super call to parent controller
|
||||||
var self = PodcastController.call(this, $scope, $http, podcast, tab);
|
PodcastController.call(this, $scope, $http, podcast, tab);
|
||||||
// Store the station podcast tab in module scope so it can be checked if the user clicks the
|
// Store the station podcast tab in module scope so it can be checked if the user clicks the
|
||||||
// Station Podcast button again - this way we don't have to go back to the server to get the ID.
|
// Station Podcast button again - this way we don't have to go back to the server to get the ID.
|
||||||
$stationPodcastTab = tab;
|
$stationPodcastTab = tab;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the tab close function to 'unset' the module-scope $stationPodcastTab
|
* Override the tab close function to 'unset' the module-scope $stationPodcastTab.
|
||||||
*
|
*
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
|
@ -181,25 +171,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
$stationPodcastTab = undefined;
|
$stationPodcastTab = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.deleteSelectedEpisodes = function () {
|
return this;
|
||||||
var episodes = self.episodeTable.getSelectedRows();
|
|
||||||
jQuery.each(episodes, function () {
|
|
||||||
$http.delete(endpoint + $scope.podcast.id + '/episodes/' + this.id + '?csrf_token=' + $scope.csrf)
|
|
||||||
.success(function () {
|
|
||||||
self.reloadEpisodeTable();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
self.openSelectedTabEditors = function () {
|
|
||||||
var episodes = self.episodeTable.getSelectedRows();
|
|
||||||
$.each(episodes, function () {
|
|
||||||
var uid = AIRTIME.library.MediaTypeStringEnum.FILE + "_" + this.file_id;
|
|
||||||
$.get(baseUrl + "library/edit-file-md/id/" + this.file_id, {format: "json"}, function (json) {
|
|
||||||
AIRTIME.playlist.fileMdEdit(json, uid);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,6 +181,34 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
*/
|
*/
|
||||||
StationPodcastController.prototype = Object.create(PodcastController.prototype);
|
StationPodcastController.prototype = Object.create(PodcastController.prototype);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the selected episodes from the station podcast feed.
|
||||||
|
*/
|
||||||
|
StationPodcastController.prototype.unpublishSelectedEpisodes = function () {
|
||||||
|
var self = this, $scope = self.$scope,
|
||||||
|
episodes = self.episodeTable.getSelectedRows();
|
||||||
|
jQuery.each(episodes, function () {
|
||||||
|
self.$http.delete(endpoint + $scope.podcast.id + '/episodes/' + this.id + '?csrf_token=' + $scope.csrf)
|
||||||
|
.success(function () {
|
||||||
|
self.reloadEpisodeTable();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open metadata editor tabs for each of the selected episodes.
|
||||||
|
*/
|
||||||
|
StationPodcastController.prototype.openSelectedTabEditors = function () {
|
||||||
|
var self = this,
|
||||||
|
episodes = self.episodeTable.getSelectedRows();
|
||||||
|
jQuery.each(episodes, function () {
|
||||||
|
var uid = AIRTIME.library.MediaTypeStringEnum.FILE + "_" + this.file_id;
|
||||||
|
jQuery.get(baseUrl + "library/edit-file-md/id/" + this.file_id, {format: "json"}, function (json) {
|
||||||
|
AIRTIME.playlist.fileMdEdit(json, uid);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the Station podcast episode table.
|
* Initialize the Station podcast episode table.
|
||||||
*
|
*
|
||||||
|
@ -223,9 +223,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
extraBtnClass : '',
|
extraBtnClass : '',
|
||||||
elementId : '',
|
elementId : '',
|
||||||
eventHandlers : {
|
eventHandlers : {
|
||||||
click: function () {
|
click: self.openSelectedTabEditors.bind(self)
|
||||||
self.openSelectedTabEditors();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteBtn: {
|
deleteBtn: {
|
||||||
|
@ -234,9 +232,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
extraBtnClass : 'btn-danger',
|
extraBtnClass : 'btn-danger',
|
||||||
elementId : '',
|
elementId : '',
|
||||||
eventHandlers : {
|
eventHandlers : {
|
||||||
click: function () {
|
click: self.unpublishSelectedEpisodes.bind(self)
|
||||||
self.deleteSelectedEpisodes();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
slideToggle: {}
|
slideToggle: {}
|
||||||
|
@ -253,12 +249,20 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
this.episodeTable = AIRTIME.podcast.initPodcastEpisodeDatatable(
|
this.episodeTable = AIRTIME.podcast.initPodcastEpisodeDatatable(
|
||||||
$scope.tab.contents.find('.podcast_episodes'),
|
$scope.tab.contents.find('.podcast_episodes'),
|
||||||
params,
|
params,
|
||||||
buttons
|
buttons,
|
||||||
|
{
|
||||||
|
hideIngestCheckboxes: true,
|
||||||
|
podcastId: $scope.podcast.id
|
||||||
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the Station podcast.
|
||||||
|
*/
|
||||||
StationPodcastController.prototype.initialize = function() {
|
StationPodcastController.prototype.initialize = function() {
|
||||||
PodcastController.prototype.initialize.call(this);
|
PodcastController.prototype.initialize.call(this);
|
||||||
|
// We want to override the default tab name behaviour and use "Station Podcast" for clarity
|
||||||
this.$scope.tab.setName(jQuery.i18n._("Station Podcast"));
|
this.$scope.tab.setName(jQuery.i18n._("Station Podcast"));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -354,30 +358,112 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _initPodcastTable() {
|
function _initPodcastEpisodeTable() {
|
||||||
PodcastTable = function(wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions) {
|
PodcastEpisodeTable = function(wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions, config) {
|
||||||
// Just call the superconstructor. For clarity/extensibility
|
this.config = config; // Internal configuration object
|
||||||
|
this._setupImportListener();
|
||||||
|
// Call the superconstructor
|
||||||
return AIRTIME.widgets.Table.call(this, wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions);
|
return AIRTIME.widgets.Table.call(this, wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions);
|
||||||
}; // Subclass AIRTIME.widgets.Table
|
}; // Subclass AIRTIME.widgets.Table
|
||||||
PodcastTable.prototype = Object.create(AIRTIME.widgets.Table.prototype);
|
PodcastEpisodeTable.prototype = Object.create(AIRTIME.widgets.Table.prototype);
|
||||||
PodcastTable.prototype.constructor = PodcastTable;
|
PodcastEpisodeTable.prototype.constructor = PodcastEpisodeTable;
|
||||||
PodcastTable.prototype._SELECTORS = Object.freeze({
|
PodcastEpisodeTable.prototype._SELECTORS = Object.freeze({
|
||||||
SELECTION_CHECKBOX: ".airtime_table_checkbox:has(input)",
|
SELECTION_CHECKBOX: ".airtime_table_checkbox:has(input)",
|
||||||
SELECTION_TABLE_ROW: "tr:has(td.airtime_table_checkbox > input)"
|
SELECTION_TABLE_ROW: "tr:has(td.airtime_table_checkbox > input)"
|
||||||
});
|
});
|
||||||
PodcastTable.prototype._datatablesCheckboxDataDelegate = function(rowData, callType, dataToSave) {
|
|
||||||
if (rowData.ingested) return null; // Don't create checkboxes for ingested items
|
/**
|
||||||
|
* @override
|
||||||
|
*
|
||||||
|
* Override the checkbox delegate function in the Table object to change
|
||||||
|
* the row's checkbox and import status columns depending on the status
|
||||||
|
* of the episode (unimported: 0, imported: 1, pending import: -1).
|
||||||
|
*
|
||||||
|
* @param rowData
|
||||||
|
* @param callType
|
||||||
|
* @param dataToSave
|
||||||
|
*
|
||||||
|
* @returns {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
PodcastEpisodeTable.prototype._datatablesCheckboxDataDelegate = function(rowData, callType, dataToSave) {
|
||||||
|
var importIcon = "<span class='sp-checked-icon checked-icon imported-flag'></span>",
|
||||||
|
pendingIcon = "<span class='loading-icon'></span>";
|
||||||
|
if (this.config.hideIngestCheckboxes && rowData.ingested && rowData.ingested != 0) {
|
||||||
|
return rowData.ingested > 0 ? importIcon : pendingIcon;
|
||||||
|
}
|
||||||
|
rowData.importIcon = (rowData.ingested != 0) ? (rowData.ingested > 0 ? importIcon : pendingIcon) : null;
|
||||||
return AIRTIME.widgets.Table.prototype._datatablesCheckboxDataDelegate.call(this, rowData, callType, dataToSave);
|
return AIRTIME.widgets.Table.prototype._datatablesCheckboxDataDelegate.call(this, rowData, callType, dataToSave);
|
||||||
};
|
};
|
||||||
// Since we're sometimes using a static source, define a separate function to fetch and 'reload' the table data
|
|
||||||
// We use this when we save the Podcast because we need to flag rows the user is ingesting
|
/**
|
||||||
PodcastTable.prototype.reload = function (id) {
|
* Reload the episode table.
|
||||||
|
* Since we're sometimes using a static source, define a separate function to fetch and reload the table data.
|
||||||
|
* We use this when we save the Podcast because we need to flag rows the user is ingesting.
|
||||||
|
*
|
||||||
|
* @param [id] optional podcast identifier
|
||||||
|
*/
|
||||||
|
PodcastEpisodeTable.prototype.reload = function (id) {
|
||||||
|
// When using static source data, we instantiate an empty table
|
||||||
|
// and pass this function the ID of the podcast we want to display.
|
||||||
|
if (id) this.config.podcastId = id;
|
||||||
var dt = this._datatable;
|
var dt = this._datatable;
|
||||||
$.get(endpoint + id + '/episodes', function (json) {
|
dt.block({
|
||||||
|
message: "",
|
||||||
|
theme: true,
|
||||||
|
applyPlatformOpacityRules: false
|
||||||
|
});
|
||||||
|
$.get(endpoint + this.config.podcastId + '/episodes', function (json) {
|
||||||
dt.fnClearTable();
|
dt.fnClearTable();
|
||||||
dt.fnAddData(JSON.parse(json));
|
dt.fnAddData(JSON.parse(json));
|
||||||
|
dt.fnDraw();
|
||||||
|
dt.unblock();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup an interval that checks for any pending imports and reloads
|
||||||
|
* the table once imports are finished.
|
||||||
|
*
|
||||||
|
* TODO: remember selection
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
PodcastEpisodeTable.prototype._setupImportListener = function () {
|
||||||
|
var self = this;
|
||||||
|
self.importListener = setInterval(function () {
|
||||||
|
var podcastId = self.config.podcastId, pendingRows = [];
|
||||||
|
if (!podcastId) return false;
|
||||||
|
var dt = self.getDatatable(), data = dt.fnGetData();
|
||||||
|
// Iterate over the table data to check for any rows pending import
|
||||||
|
$.each(data, function () {
|
||||||
|
if (this.ingested == -1) {
|
||||||
|
pendingRows.push(this.guid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(pendingRows);
|
||||||
|
if (pendingRows.length > 0) {
|
||||||
|
$.get(endpoint + podcastId + '/episodes', function (json) {
|
||||||
|
data = JSON.parse(json);
|
||||||
|
var delta = false;
|
||||||
|
$.each(data, function () {
|
||||||
|
var idx = pendingRows.indexOf(this.guid);
|
||||||
|
console.log(idx);
|
||||||
|
if (idx > -1 && this.ingested != -1) {
|
||||||
|
delta = true;
|
||||||
|
pendingRows.slice(idx, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (delta) { // Has there been a change?
|
||||||
|
// We already have the data, so there's no reason to call
|
||||||
|
// reload() here; this also provides a smoother transition
|
||||||
|
dt.fnClearTable();
|
||||||
|
dt.fnAddData(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 15000); // Run every 15 seconds
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -444,19 +530,39 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import one or more podcast episodes.
|
||||||
|
*
|
||||||
|
* @param {Array} episodes array of episode data to be imported
|
||||||
|
* @param {PodcastEpisodeTable} dt PodcastEpisode table containing the data
|
||||||
|
*/
|
||||||
|
mod.importSelectedEpisodes = function (episodes, dt) {
|
||||||
|
$.each(episodes, function () {
|
||||||
|
var podcastId = this.podcast_id;
|
||||||
|
$.post(endpoint + podcastId + '/episodes', JSON.stringify({
|
||||||
|
csrf_token: $("#csrf").val(),
|
||||||
|
episode: this
|
||||||
|
}), function () {
|
||||||
|
dt.reload(podcastId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the internal datatable for the podcast editor view to hold episode data passed back from the server.
|
* Initialize the internal datatable for the podcast editor view to hold episode data passed back from the server.
|
||||||
*
|
*
|
||||||
* Selection for the internal table represents episodes marked for ingest and is disabled for ingested episodes.
|
* Selection for the internal table represents episodes marked for ingest and is disabled for ingested episodes.
|
||||||
*
|
*
|
||||||
* @param {Object} domNode the jQuery DOM node to create the table inside.
|
* @param {jQuery} domNode the jQuery DOM node to create the table inside.
|
||||||
* @param {Object} params JSON object containing datatables parameters to override
|
* @param {Object} params JSON object containing datatables parameters to override
|
||||||
* @param {Object} buttons JSON object containing datatables button parameters
|
* @param {Object} buttons JSON object containing datatables button parameters
|
||||||
|
* @param {Object} config JSON object containing internal PodcastEpisodeTable parameters
|
||||||
|
* @param {boolean} config.hideIngestCheckboxes flag denoting whether or not to hide checkboxes for ingested items
|
||||||
*
|
*
|
||||||
* @returns {*} the created Table object
|
* @returns {Table} the created Table object
|
||||||
*/
|
*/
|
||||||
mod.initPodcastEpisodeDatatable = function(domNode, params, buttons) {
|
mod.initPodcastEpisodeDatatable = function (domNode, params, buttons, config) {
|
||||||
if ('slideToggle' in buttons)
|
if ('slideToggle' in buttons) {
|
||||||
buttons = $.extend(true, {
|
buttons = $.extend(true, {
|
||||||
slideToggle: {
|
slideToggle: {
|
||||||
title: '',
|
title: '',
|
||||||
|
@ -466,7 +572,8 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
eventHandlers: {}
|
eventHandlers: {}
|
||||||
}
|
}
|
||||||
}, buttons);
|
}, buttons);
|
||||||
params = $.extend(params,
|
}
|
||||||
|
params = $.extend(true, params,
|
||||||
{
|
{
|
||||||
oColVis: {
|
oColVis: {
|
||||||
sAlign: 'right',
|
sAlign: 'right',
|
||||||
|
@ -480,15 +587,16 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (typeof PodcastTable === 'undefined') {
|
if (typeof PodcastEpisodeTable === 'undefined') {
|
||||||
_initPodcastTable();
|
_initPodcastEpisodeTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
var podcastEpisodesTableWidget = new PodcastTable(
|
var podcastEpisodesTableWidget = new PodcastEpisodeTable(
|
||||||
domNode, // DOM node to create the table inside.
|
domNode, // DOM node to create the table inside.
|
||||||
true, // Enable item selection
|
true, // Enable item selection
|
||||||
buttons, // Toolbar buttons
|
buttons, // Toolbar buttons
|
||||||
params // Datatables overrides.
|
params, // Datatables overrides.
|
||||||
|
config // Internal config
|
||||||
);
|
);
|
||||||
|
|
||||||
podcastEpisodesTableWidget.getDatatable().addTitles("td");
|
podcastEpisodesTableWidget.getDatatable().addTitles("td");
|
||||||
|
|
|
@ -31,7 +31,6 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
self._selectedRowVisualIdxMax = -1;
|
self._selectedRowVisualIdxMax = -1;
|
||||||
self._$wrapperDOMNode = null;
|
self._$wrapperDOMNode = null;
|
||||||
self._toolbarButtons = null;
|
self._toolbarButtons = null;
|
||||||
|
|
||||||
//Save some of the constructor parameters
|
//Save some of the constructor parameters
|
||||||
self._$wrapperDOMNode = $(wrapperDOMNode);
|
self._$wrapperDOMNode = $(wrapperDOMNode);
|
||||||
self._toolbarButtons = toolbarButtons;
|
self._toolbarButtons = toolbarButtons;
|
||||||
|
@ -44,7 +43,7 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
// If selection is enabled, add in the checkbox column.
|
// If selection is enabled, add in the checkbox column.
|
||||||
if (bItemSelection) {
|
if (bItemSelection) {
|
||||||
dataTablesOptions["aoColumns"].unshift(
|
dataTablesOptions["aoColumns"].unshift(
|
||||||
/* Checkbox */ { "sTitle" : "", "mData" : self._datatablesCheckboxDataDelegate, "bSortable" : false , "bSearchable" : false , "sWidth" : "16px" , "sClass" : "airtime_table_checkbox" }
|
/* Checkbox */ { "sTitle" : "", "mData" : self._datatablesCheckboxDataDelegate.bind(this), "bSortable" : false , "bSearchable" : false , "sWidth" : "24px" , "sClass" : "airtime_table_checkbox" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
}),
|
}),
|
||||||
"oColVis": {
|
"oColVis": {
|
||||||
"sAlign": "right",
|
"sAlign": "right",
|
||||||
"aiExclude": self.colVisExcludeColumns,
|
"aiExclude": self._colVisExcludeColumns,
|
||||||
"buttonText": $.i18n._("Columns"),
|
"buttonText": $.i18n._("Columns"),
|
||||||
"iOverlayFade": 0
|
"iOverlayFade": 0
|
||||||
},
|
},
|
||||||
|
@ -428,7 +427,6 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
|
|
||||||
//Static initializers / Class variables
|
//Static initializers / Class variables
|
||||||
|
|
||||||
/** Predefined toolbar buttons that you can add to the table. Use getStandardToolbarButtons(). */
|
|
||||||
Table.prototype._SELECTORS = Object.freeze({
|
Table.prototype._SELECTORS = Object.freeze({
|
||||||
SELECTION_CHECKBOX: ".airtime_table_checkbox",
|
SELECTION_CHECKBOX: ".airtime_table_checkbox",
|
||||||
SELECTION_TABLE_ROW: "tr"
|
SELECTION_TABLE_ROW: "tr"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue