Update to podcast frontend
This commit is contained in:
parent
febc5fa99d
commit
375d83ab43
6 changed files with 62 additions and 27 deletions
|
@ -139,13 +139,20 @@ class Podcast extends BasePodcast
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private static function _generatePodcastArray($podcast, $rss) {
|
private static function _generatePodcastArray($podcast, $rss) {
|
||||||
$podcastArray = $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
$ingestedEpisodes = PodcastEpisodesQuery::create()
|
||||||
|
->findByDbPodcastId($podcast->getDbId());
|
||||||
|
$episodeIds = array();
|
||||||
|
foreach ($ingestedEpisodes as $e) {
|
||||||
|
array_push($episodeIds, $e->getDbEpisodeGuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
$podcastArray = $podcast->toArray(BasePeer::TYPE_FIELDNAME);
|
||||||
$podcastArray["episodes"] = array();
|
$podcastArray["episodes"] = array();
|
||||||
foreach ($rss->get_items() as $item) {
|
foreach ($rss->get_items() as $item) {
|
||||||
/** @var SimplePie_Item $item */
|
/** @var SimplePie_Item $item */
|
||||||
array_push($podcastArray["episodes"], array(
|
array_push($podcastArray["episodes"], array(
|
||||||
"guid" => $item->get_id(),
|
"guid" => $item->get_id(),
|
||||||
|
"ingested" => in_array($item->get_id(), $episodeIds),
|
||||||
"title" => $item->get_title(),
|
"title" => $item->get_title(),
|
||||||
"author" => $item->get_author()->get_name(),
|
"author" => $item->get_author()->get_name(),
|
||||||
"description" => $item->get_description(),
|
"description" => $item->get_description(),
|
||||||
|
|
|
@ -90,9 +90,6 @@ class Rest_PodcastController extends Zend_Rest_Controller
|
||||||
$this->_helper->json->sendJson(array(
|
$this->_helper->json->sendJson(array(
|
||||||
"podcast"=>json_encode($podcast),
|
"podcast"=>json_encode($podcast),
|
||||||
"html"=>$this->view->render($path),
|
"html"=>$this->view->render($path),
|
||||||
"type"=>"podcast", // TODO: get rid of these extraneous fields
|
|
||||||
"id"=>$podcast["id"]
|
|
||||||
// "id"=>$podcast->getDbId()
|
|
||||||
));
|
));
|
||||||
|
|
||||||
// $this->getResponse()
|
// $this->getResponse()
|
||||||
|
|
|
@ -58,6 +58,15 @@ var i18n_days_short = [
|
||||||
$.i18n._("Sa")
|
$.i18n._("Sa")
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var HTTPMethods = Object.freeze({
|
||||||
|
GET: "GET",
|
||||||
|
POST: "POST",
|
||||||
|
PUT: "PUT",
|
||||||
|
PATCH: "PATCH",
|
||||||
|
DELETE: "DELETE",
|
||||||
|
OPTIONS: "OPTIONS"
|
||||||
|
});
|
||||||
|
|
||||||
var dateStartId = "#sb_date_start",
|
var dateStartId = "#sb_date_start",
|
||||||
timeStartId = "#sb_time_start",
|
timeStartId = "#sb_time_start",
|
||||||
dateEndId = "#sb_date_end",
|
dateEndId = "#sb_date_end",
|
||||||
|
@ -69,7 +78,7 @@ function getDatatablesStrings(overrideDict) {
|
||||||
"sEmptyTable": $.i18n._("No data available in table"),
|
"sEmptyTable": $.i18n._("No data available in table"),
|
||||||
"sInfo": $.i18n._("Showing _START_ to _END_ of _TOTAL_ entries"),
|
"sInfo": $.i18n._("Showing _START_ to _END_ of _TOTAL_ entries"),
|
||||||
"sInfoEmpty": $.i18n._("Showing 0 to 0 of 0 entries"),
|
"sInfoEmpty": $.i18n._("Showing 0 to 0 of 0 entries"),
|
||||||
"sInfoFiltered": $.i18n._("(filtered from _MAX_ total entries)"),
|
"sInfoFiltered": "", // $.i18n._("(filtered from _MAX_ total entries)"),
|
||||||
"sInfoPostFix": $.i18n._(""),
|
"sInfoPostFix": $.i18n._(""),
|
||||||
"sInfoThousands": $.i18n._(","),
|
"sInfoThousands": $.i18n._(","),
|
||||||
"sLengthMenu": $.i18n._("Show _MENU_"),
|
"sLengthMenu": $.i18n._("Show _MENU_"),
|
||||||
|
|
|
@ -25,7 +25,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
podcastData.episodes = episodeTable.getSelectedRows();
|
podcastData.episodes = episodeTable.getSelectedRows();
|
||||||
$http.put(endpoint + $scope.podcast.id, { csrf_token: jQuery("#csrf").val(), podcast: podcastData })
|
$http.put(endpoint + $scope.podcast.id, { csrf_token: jQuery("#csrf").val(), podcast: podcastData })
|
||||||
.success(function() {
|
.success(function() {
|
||||||
// TODO
|
// TODO refresh the table here somehow..
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,15 +36,20 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function _bulkAction(method, callback) {
|
function _bulkAction(method, callback) {
|
||||||
var selected = $("#podcast_table").find(".selected"),
|
var ids = [], selectedData = AIRTIME.library.podcastTableWidget.getSelectedRows();
|
||||||
ids = [];
|
|
||||||
var selectedData = AIRTIME.library.podcastTableWidget.getSelectedRows();
|
|
||||||
selectedData.forEach(function(el) {
|
selectedData.forEach(function(el) {
|
||||||
ids.push(el.id);
|
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+el.id;
|
||||||
|
var t = AIRTIME.tabs.get(uid);
|
||||||
|
if (t && method == HTTPMethods.DELETE) {
|
||||||
|
t.close();
|
||||||
|
}
|
||||||
|
if (!(t && method == HTTPMethods.GET)) ids.push(el.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (ids.length > 0) {
|
||||||
// Bulk methods should use post because we're sending data in the request body
|
// Bulk methods should use post because we're sending data in the request body
|
||||||
$.post(endpoint + "bulk", { csrf_token: $("#csrf").val(), method: method, ids: ids }, callback);
|
$.post(endpoint + "bulk", {csrf_token: $("#csrf").val(), method: method, ids: ids}, callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _bootstrapAngularApp(podcast, tab, table) {
|
function _bootstrapAngularApp(podcast, tab, table) {
|
||||||
|
@ -81,7 +86,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
};
|
};
|
||||||
|
|
||||||
mod.editSelectedPodcasts = function() {
|
mod.editSelectedPodcasts = function() {
|
||||||
_bulkAction("GET", function(json) {
|
_bulkAction(HTTPMethods.GET, function(json) {
|
||||||
json.forEach(function(el) {
|
json.forEach(function(el) {
|
||||||
var podcast = JSON.parse(el.podcast);
|
var podcast = JSON.parse(el.podcast);
|
||||||
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
|
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
|
||||||
|
@ -94,7 +99,7 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
|
|
||||||
mod.deleteSelectedPodcasts = function() {
|
mod.deleteSelectedPodcasts = function() {
|
||||||
if (confirm($.i18n._("Are you sure you want to delete the selected podcasts from your library?"))) {
|
if (confirm($.i18n._("Are you sure you want to delete the selected podcasts from your library?"))) {
|
||||||
_bulkAction("DELETE", function () {
|
_bulkAction(HTTPMethods.DELETE, function () {
|
||||||
AIRTIME.library.podcastDataTable.fnDraw();
|
AIRTIME.library.podcastDataTable.fnDraw();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -110,10 +115,26 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
/* 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" }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var PodcastTable = function(wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions) {
|
||||||
|
// Just call the superconstructor. For clarity/extensibility
|
||||||
|
return AIRTIME.widgets.Table.call(this, wrapperDOMNode, bItemSelection, toolbarButtons, dataTablesOptions);
|
||||||
|
}; // Subclass AIRTIME.widgets.Table
|
||||||
|
PodcastTable.prototype = Object.create(AIRTIME.widgets.Table.prototype);
|
||||||
|
PodcastTable.prototype.constructor = PodcastTable;
|
||||||
|
PodcastTable.prototype._SELECTORS = Object.freeze({
|
||||||
|
SELECTION_CHECKBOX: ".airtime_table_checkbox:has(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
|
||||||
|
return AIRTIME.widgets.Table.prototype._datatablesCheckboxDataDelegate.call(this, rowData, callType, dataToSave);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This method is static, so use AIRTIME.widgets.Table
|
||||||
var podcastToolbarButtons = AIRTIME.widgets.Table.getStandardToolbarButtons();
|
var podcastToolbarButtons = AIRTIME.widgets.Table.getStandardToolbarButtons();
|
||||||
|
|
||||||
// Set up the div with id "podcast_table" as a datatable.
|
// Set up the div with id "podcast_table" as a datatable.
|
||||||
var podcastEpisodesTableWidget = new AIRTIME.widgets.Table(
|
var podcastEpisodesTableWidget = new PodcastTable(
|
||||||
AIRTIME.tabs.getActiveTab().contents.find('#podcast_episodes'), // DOM node to create the table inside.
|
AIRTIME.tabs.getActiveTab().contents.find('#podcast_episodes'), // DOM node to create the table inside.
|
||||||
true, // Enable item selection
|
true, // Enable item selection
|
||||||
podcastToolbarButtons, // Toolbar buttons
|
podcastToolbarButtons, // Toolbar buttons
|
||||||
|
|
|
@ -316,12 +316,12 @@ var AIRTIME = (function(AIRTIME){
|
||||||
/**
|
/**
|
||||||
* Given a tab id, get the corresponding Tab object
|
* Given a tab id, get the corresponding Tab object
|
||||||
*
|
*
|
||||||
* @param {int} id the tab id of the Tab to retrieve
|
* @param {int|string} id the tab or object ID of the Tab to retrieve
|
||||||
* @returns {Tab|undefined} the Tab object with the given id, or undefined
|
* @returns {Tab|undefined} the Tab object with the given ID, or undefined
|
||||||
* if no Tab with the given id exists
|
* if no Tab with the given ID exists
|
||||||
*/
|
*/
|
||||||
mod.get = function(id) {
|
mod.get = function(id) {
|
||||||
return $openTabs[$tabMap[id]];
|
return $.isNumeric(id) ? $openTabs[$tabMap[id]] : $openTabs[id];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,11 +23,6 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
MULTI_CTRL : 2
|
MULTI_CTRL : 2
|
||||||
};
|
};
|
||||||
|
|
||||||
// Internal enum for repeated jQuery selectors
|
|
||||||
self._SELECTORS = Object.freeze({
|
|
||||||
SELECTION_CHECKBOX: ".airtime_table_checkbox"
|
|
||||||
});
|
|
||||||
|
|
||||||
//Member variables
|
//Member variables
|
||||||
self._datatable = null;
|
self._datatable = null;
|
||||||
self._selectedRows = []; //An array containing the underlying objects for each selected row. (Easy to use!)
|
self._selectedRows = []; //An array containing the underlying objects for each selected row. (Easy to use!)
|
||||||
|
@ -109,8 +104,8 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
* than having a per-row callback...)
|
* than having a per-row callback...)
|
||||||
*/
|
*/
|
||||||
if (bItemSelection) {
|
if (bItemSelection) {
|
||||||
$(self._datatable, 'tbody tr').on('click contextmenu', 'tr', function (e) {
|
$(self._datatable, 'tbody tr').on('click contextmenu', self._SELECTORS.SELECTION_TABLE_ROW, function (e) {
|
||||||
var aData = self._datatable.fnGetData($(this).index()); // $(this).data(); //Neat trick - thanks DataTables!
|
var aData = self._datatable.fnGetData($(this).index());
|
||||||
var iDisplayIndex = $(this).index(); //The index of the row in the current page in the table.
|
var iDisplayIndex = $(this).index(); //The index of the row in the current page in the table.
|
||||||
var nRow = this;
|
var nRow = this;
|
||||||
|
|
||||||
|
@ -427,6 +422,12 @@ var AIRTIME = (function(AIRTIME) {
|
||||||
//Static initializers / Class variables
|
//Static initializers / Class variables
|
||||||
|
|
||||||
/** Predefined toolbar buttons that you can add to the table. Use getStandardToolbarButtons(). */
|
/** Predefined toolbar buttons that you can add to the table. Use getStandardToolbarButtons(). */
|
||||||
|
Table.prototype._SELECTORS = Object.freeze({
|
||||||
|
SELECTION_CHECKBOX: ".airtime_table_checkbox",
|
||||||
|
SELECTION_TABLE_ROW: "tr"
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
Table.TOOLBAR_BUTTON_ROLES = {
|
Table.TOOLBAR_BUTTON_ROLES = {
|
||||||
NEW : 0,
|
NEW : 0,
|
||||||
EDIT : 1,
|
EDIT : 1,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue