diff --git a/airtime_mvc/application/services/PodcastEpisodeService.php b/airtime_mvc/application/services/PodcastEpisodeService.php index e2e2aed1c..9c3628505 100644 --- a/airtime_mvc/application/services/PodcastEpisodeService.php +++ b/airtime_mvc/application/services/PodcastEpisodeService.php @@ -323,6 +323,10 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir $ingested = in_array($itemId, $episodeIds) ? (empty($episodeFiles[$itemId]) ? -1 : 1) : 0; $file = $ingested > 0 && !empty($episodeFiles[$itemId]) ? CcFiles::getSanitizedFileById($episodeFiles[$itemId]) : array(); + // If the analyzer hasn't finished with the file, leave it as pending + if (!empty($file) && $file["import_status"] == CcFiles::IMPORT_STATUS_PENDING) { + $ingested = -1; + } array_push($episodesArray, array( "podcast_id" => $podcast->getDbId(), diff --git a/airtime_mvc/public/css/dashboard.css b/airtime_mvc/public/css/dashboard.css index 808b1f8c9..c44007dbd 100644 --- a/airtime_mvc/public/css/dashboard.css +++ b/airtime_mvc/public/css/dashboard.css @@ -335,6 +335,7 @@ thead th.ui-state-default:focus { #sb_show_filter { right: 0; + max-width: 125px; position: absolute; } diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index cc36fb95f..493bd7673 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -4011,6 +4011,10 @@ li .ui-state-hover { top: 74px !important; } +.angular_wrapper > .btn-toolbar { + padding: 5px 0 0 5px; +} + .podcast-metadata p { text-align: center; padding: 0 10px; diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index 9297c8d3c..0773e8c1c 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -1486,13 +1486,6 @@ var AIRTIME = (function(AIRTIME) { click: function () { var data = [], episodes = mod.podcastEpisodeTableWidget.getSelectedRows(); $.each(episodes, function () { - // If the file exists but the ftype is empty, the file hasn't finished being - // analyzed. This forces the deletion, but causes the analyzer to throw an error... - // I'm opting for more consistent behaviour (if it looks like a file is imported, - // the user should be able to delete it, rather than it seeming like the delete - // button did nothing), but maybe the answer is to add an additional state that - // checks if the file is finished being analyzed? -- Duncan FIXME - if (this.file.ftype === "") { this.file.ftype = "audioclip"; } data.push({id: this.file.id, type: this.file.ftype}); }); mod.fnDeleteItems(data); diff --git a/airtime_mvc/public/js/airtime/library/podcast.js b/airtime_mvc/public/js/airtime/library/podcast.js index 889219536..e1c9d6a14 100644 --- a/airtime_mvc/public/js/airtime/library/podcast.js +++ b/airtime_mvc/public/js/airtime/library/podcast.js @@ -33,21 +33,6 @@ var AIRTIME = (function (AIRTIME) { $scope.csrf = jQuery("#csrf").val(); tab.contents.find("table").attr("id", "podcast_episodes_" + podcast.id); - /** - * Override the switchTo function to reload the table when the tab is focused. - * Should help to reduce the number of cases where the frontend doesn't match the state - * of the backend (due to automatic ingestion). - * - * Note that these cases should already be very few and far between. - * - * TODO: make sure this doesn't noticeably slow performance - * XXX: it's entirely possible that this (in the angular app) is not where we want this function... - */ - tab.switchTo = function () { - AIRTIME.tabs.Tab.prototype.switchTo.call(this); - self.reloadEpisodeTable(); - }; - /** * Save and update the podcast object. */ @@ -74,72 +59,6 @@ var AIRTIME = (function (AIRTIME) { return self; } - /** - * Initialize the podcast episode table. - * - * @private - */ - PodcastController.prototype._initTable = function() { - /* - * Remove the episode table for imported podcasts since its functionality is replicated in the left-hand pane - * - var self = this, - $scope = self.$scope; - // We want to fetch the data statically for imported podcasts because we would need to implement sorting - // in a very convoluted way on the backend to accommodate the nonexistent rows for uningested episodes - var params = { - 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 : [ - { "sTitle" : "" , "mDataProp" : "guid" , "sClass" : "podcast_episodes_guid" , "bVisible" : false }, - { "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" }, - { "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" }, - { "sTitle" : $.i18n._("Description") , "mDataProp" : "description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" }, - { "sTitle" : $.i18n._("Link") , "mDataProp" : "link" , "sClass" : "podcast_episodes_link" , "sWidth" : "170px" }, - { "sTitle" : $.i18n._("Publication Date") , "mDataProp" : "pub_date" , "sClass" : "podcast_episodes_pub_date" , "sWidth" : "170px" } - ] - }, - buttons = { - slideToggle: {}, - importBtn: { - title : $.i18n._('Import Selected'), - iconClass : '', - extraBtnClass : 'btn-new', - elementId : '', - eventHandlers : { - click: function () { - mod.importSelectedEpisodes(self.episodeTable.getSelectedRows(), self.episodeTable); - } - }, - validateConstraints: function () { - // Only importable rows can be selected - return this.getSelectedRows().length >= 1; - } - } - }; - self.episodeTable = AIRTIME.podcast.initPodcastEpisodeDatatable( - $scope.tab.contents.find('.podcast_episodes'), - params, - buttons, - { - hideIngestCheckboxes: true, - podcastId: $scope.podcast.id - } - ); - self.reloadEpisodeTable(); - */ - }; - - /** - * Reload the podcast episode table. - */ - PodcastController.prototype.reloadEpisodeTable = function() { - this.episodeTable.reload(); - }; - /** * Initialize the controller. * @@ -150,7 +69,6 @@ var AIRTIME = (function (AIRTIME) { // TODO: this solves a race condition, but we should look for the root cause AIRTIME.tabs.onResize(); self.$scope.tab.setName(self.$scope.podcast.title); - self._initTable(); // Add an onclose hook to the tab to remove the table object and the // import listener so we don't cause memory leaks. if (self.episodeTable) { @@ -182,15 +100,31 @@ var AIRTIME = (function (AIRTIME) { $stationPodcastTab = tab; /** - * Override the tab close function to 'unset' the module-scope $stationPodcastTab. - * * @override + * + * Override the tab close function to 'unset' the module-scope $stationPodcastTab. */ tab.close = function () { AIRTIME.tabs.Tab.prototype.close.call(this); $stationPodcastTab = undefined; }; + /** + * @override + * + * Override the switchTo function to reload the table when the tab is focused. + * Should help to reduce the number of cases where the frontend doesn't match the state + * of the backend (due to automatic ingestion). + * + * Note that these cases should already be very few and far between. + * + * XXX: it's entirely possible that this (in the angular module) is not where we want this function... + */ + tab.switchTo = function () { + AIRTIME.tabs.Tab.prototype.switchTo.call(this); + self.reloadEpisodeTable(); + }; + return this; } @@ -259,7 +193,7 @@ var AIRTIME = (function (AIRTIME) { params = { sAjaxSource : endpoint + $scope.podcast.id + '/episodes', aoColumns: [ - // TODO: it might be dangerous to use CcFiles here? We should alias this instead + // TODO: it might be wrong to use CcFiles here? We should alias this instead /* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "CcFiles.track_title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" }, /* Description */ { "sTitle" : $.i18n._("Description") , "mDataProp" : "CcFiles.description" , "sClass" : "podcast_episodes_description" , "sWidth" : "300px" } ] @@ -283,12 +217,13 @@ var AIRTIME = (function (AIRTIME) { 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")); + self._initTable(); }; /** - * Reload the Station podcast episode table. - * * @override + * + * Reload the Station podcast episode table. */ StationPodcastController.prototype.reloadEpisodeTable = function() { this.episodeTable.getDatatable().fnDraw();