diff --git a/airtime_mvc/application/configs/ACL.php b/airtime_mvc/application/configs/ACL.php index 74be31809..52ba6fa7b 100644 --- a/airtime_mvc/application/configs/ACL.php +++ b/airtime_mvc/application/configs/ACL.php @@ -37,6 +37,7 @@ $ccAcl->add(new Zend_Acl_Resource('library')) ->add(new Zend_Acl_Resource('rest:show-image')) ->add(new Zend_Acl_Resource('rest:podcast')) ->add(new Zend_Acl_Resource('rest:podcast-episodes')) + ->add(new Zend_Acl_Resource('podcast')) ->add(new Zend_Acl_Resource('billing')) ->add(new Zend_Acl_Resource('thank-you')) ->add(new Zend_Acl_Resource('provisioning')) @@ -76,6 +77,7 @@ $ccAcl->allow('G', 'index') ->allow('H', 'rest:media') ->allow('H', 'rest:podcast') ->allow('H', 'rest:podcast-episodes') + ->allow('H', 'podcast') ->allow('H', 'preference', 'is-import-in-progress') ->allow('H', 'usersettings') ->allow('H', 'plupload') diff --git a/airtime_mvc/application/configs/navigation.php b/airtime_mvc/application/configs/navigation.php index e61ad2986..7ab7b5fb7 100644 --- a/airtime_mvc/application/configs/navigation.php +++ b/airtime_mvc/application/configs/navigation.php @@ -8,6 +8,13 @@ * the navigation container below. */ $pages = array( + array( + 'label' => ""._('My Podcast'), + 'module' => 'default', + 'controller' => 'podcast', + 'action' => 'station', + 'resource' => 'podcast' + ), array( 'label' => ""._('Radio Page'), 'uri' => '/', diff --git a/airtime_mvc/application/controllers/PodcastController.php b/airtime_mvc/application/controllers/PodcastController.php new file mode 100644 index 000000000..afc367880 --- /dev/null +++ b/airtime_mvc/application/controllers/PodcastController.php @@ -0,0 +1,35 @@ +view->headScript(); + AirtimeTableView::injectTableJavaScriptDependencies($headScript, $baseUrl, $CC_CONFIG['airtime_version']); + + $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/library.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); + $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/events/library_showbuilder.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); + + $this->view->headScript()->appendFile($baseUrl.'js/airtime/widgets/table.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); + $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/podcast.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); + + $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']); + $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.min.css?'.$CC_CONFIG['airtime_version']); + + $this->view->headLink()->appendStylesheet($baseUrl.'css/station_podcast.css?'.$CC_CONFIG['airtime_version']); + $this->view->headLink()->appendStylesheet($baseUrl.'css/dashboard.css?'.$CC_CONFIG['airtime_version']); + } + + /** + * Renders the Station podcast view + */ + public function stationAction() { + $stationPodcastId = Application_Model_Preference::getStationPodcastId(); + $podcast = Application_Service_PodcastService::getPodcastById($stationPodcastId); + $this->view->podcast = json_encode($podcast); + $this->view->form = new Application_Form_StationPodcast(); + } + +} \ No newline at end of file diff --git a/airtime_mvc/application/forms/PodcastPreferences.php b/airtime_mvc/application/forms/PodcastPreferences.php index be8e84b39..a5706819b 100644 --- a/airtime_mvc/application/forms/PodcastPreferences.php +++ b/airtime_mvc/application/forms/PodcastPreferences.php @@ -3,28 +3,26 @@ class Application_Form_PodcastPreferences extends Zend_Form_SubForm { public function init() { - $this->setDecorators(array( - array('ViewScript', array('viewScript' => 'form/preferences_podcast.phtml')) - )); - $isPrivate = Application_Model_Preference::getStationPodcastPrivacy(); - $stationPodcastPrivacy = new Zend_Form_Element_Radio('stationPodcastPrivacy'); - $stationPodcastPrivacy->setLabel(_('My Podcast Feed Privacy')); + $stationPodcastPrivacy = new Zend_Form_Element_Radio("stationPodcastPrivacy"); + $stationPodcastPrivacy->setLabel(_('Feed Privacy')); $stationPodcastPrivacy->setMultiOptions(array( _("Public"), _("Private"), )); $stationPodcastPrivacy->setValue($isPrivate); + $stationPodcastPrivacy->setDecorators(array('ViewHelper', 'Label')); $this->addElement($stationPodcastPrivacy); $stationPodcast = PodcastQuery::create()->findOneByDbId(Application_Model_Preference::getStationPodcastId()); $url = $stationPodcast->getDbUrl(); - $feedUrl = new Zend_Form_Element_Text("stationPodcastFeedUrl:"); + $feedUrl = new Zend_Form_Element_Text("stationPodcastFeedUrl"); $feedUrl->setAttrib('class', 'input_text') ->setAttrib('disabled', 'disabled') ->setRequired(false) - ->setLabel(_("My Podcast Feed URL")) + ->setLabel(_("Feed URL")) ->setValue($url); + $feedUrl->setDecorators(array('ViewHelper', 'Label')); $this->addElement($feedUrl); } diff --git a/airtime_mvc/application/forms/Preferences.php b/airtime_mvc/application/forms/Preferences.php index e41361b6f..cb201cd2b 100644 --- a/airtime_mvc/application/forms/Preferences.php +++ b/airtime_mvc/application/forms/Preferences.php @@ -26,10 +26,6 @@ class Application_Form_Preferences extends Zend_Form $this->addSubForm($general_pref, 'preferences_general'); - // Station Podcast form - $podcastPreferences = new Application_Form_PodcastPreferences(); - $this->addSubForm($podcastPreferences, 'preferences_podcast'); - //tunein form $tuneinPreferences = new Application_Form_TuneInPreferences(); $this->addSubForm($tuneinPreferences, 'preferences_tunein'); diff --git a/airtime_mvc/application/forms/StationPodcast.php b/airtime_mvc/application/forms/StationPodcast.php new file mode 100644 index 000000000..e4e8ec9b6 --- /dev/null +++ b/airtime_mvc/application/forms/StationPodcast.php @@ -0,0 +1,11 @@ +addSubForm($podcastPreferences, 'preferences_podcast'); + } + +} \ No newline at end of file diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index bc60d7e30..bbd3d1572 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -99,7 +99,7 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= $disk = $partitions[0]; $used = $disk->totalSpace-$disk->totalFreeSpace; $total = $disk->totalSpace; - echo "var remainingDiskSpace = ".$disk->totalFreeSpace; + echo "var remainingDiskSpace = ".$disk->totalFreeSpace.";"; ?>
diff --git a/airtime_mvc/application/modules/rest/controllers/PodcastController.php b/airtime_mvc/application/modules/rest/controllers/PodcastController.php index 441cf37e2..5acf17674 100644 --- a/airtime_mvc/application/modules/rest/controllers/PodcastController.php +++ b/airtime_mvc/application/modules/rest/controllers/PodcastController.php @@ -188,14 +188,19 @@ class Rest_PodcastController extends Zend_Rest_Controller $this->_helper->json->sendJson($responseBody); } + /** + * @throws PodcastNotFoundException + * + * @deprecated + */ public function stationAction() { $stationPodcastId = Application_Model_Preference::getStationPodcastId(); $podcast = Application_Service_PodcastService::getPodcastById($stationPodcastId); - $path = 'podcast/station_podcast.phtml'; + $path = 'podcast/station.phtml'; $this->view->podcast = $podcast; $this->_helper->json->sendJson(array( "podcast" => json_encode($podcast), - "html" => $this->view->render($path), + "html" => $this->view->render($path) )); } diff --git a/airtime_mvc/application/services/PodcastService.php b/airtime_mvc/application/services/PodcastService.php index 71648c137..fdfff94fb 100644 --- a/airtime_mvc/application/services/PodcastService.php +++ b/airtime_mvc/application/services/PodcastService.php @@ -281,7 +281,7 @@ class Application_Service_PodcastService // Check the StationPodcast table rather than checking // the station podcast ID key in preferences for extensibility $podcast = StationPodcastQuery::create()->findOneByDbPodcastId($podcastId); - $path = $podcast ? 'podcast/station_podcast.phtml' : 'podcast/podcast.phtml'; + $path = $podcast ? 'podcast/station.phtml' : 'podcast/podcast.phtml'; $podcast = Application_Service_PodcastService::getPodcastById($podcastId); return array( "podcast" => json_encode($podcast), diff --git a/airtime_mvc/application/views/scripts/form/preferences.phtml b/airtime_mvc/application/views/scripts/form/preferences.phtml index 0746cc747..58fd10ea2 100644 --- a/airtime_mvc/application/views/scripts/form/preferences.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences.phtml @@ -3,11 +3,6 @@ element->getSubform('preferences_general') ?> -

-
- element->getSubform('preferences_podcast') ?> -
-

element->getSubform('preferences_tunein') ?> diff --git a/airtime_mvc/application/views/scripts/form/preferences_podcast.phtml b/airtime_mvc/application/views/scripts/form/preferences_podcast.phtml index d7feb4249..bfea8ae3f 100644 --- a/airtime_mvc/application/views/scripts/form/preferences_podcast.phtml +++ b/airtime_mvc/application/views/scripts/form/preferences_podcast.phtml @@ -1,6 +1,4 @@
-
- element->getElement('stationPodcastPrivacy')->render() ?> - element->getElement('stationPodcastFeedUrl')->render() ?> -
+ element->getElement('stationPodcastPrivacy')->render() ?> + element->getElement('stationPodcastFeedUrl')->render() ?>
diff --git a/airtime_mvc/application/views/scripts/podcast/podcast.phtml b/airtime_mvc/application/views/scripts/podcast/podcast.phtml index 13745479b..9cb196f9c 100644 --- a/airtime_mvc/application/views/scripts/podcast/podcast.phtml +++ b/airtime_mvc/application/views/scripts/podcast/podcast.phtml @@ -7,11 +7,14 @@
+ diff --git a/airtime_mvc/application/views/scripts/podcast/station_podcast.phtml b/airtime_mvc/application/views/scripts/podcast/station_podcast.phtml deleted file mode 100644 index 46302b461..000000000 --- a/airtime_mvc/application/views/scripts/podcast/station_podcast.phtml +++ /dev/null @@ -1,99 +0,0 @@ -
-
-

- -

- - - -
-
- -
- -
- -
-
- -
-
- -
- -
-
\ No newline at end of file diff --git a/airtime_mvc/public/css/station_podcast.css b/airtime_mvc/public/css/station_podcast.css new file mode 100644 index 000000000..d8289fc4c --- /dev/null +++ b/airtime_mvc/public/css/station_podcast.css @@ -0,0 +1,52 @@ +#station_podcast { + position: relative; + width: 100%; + height: 100%; +} + +#station_podcast .angular_wrapper { + flex-flow: row; + overflow: hidden; +} + +#station_podcast .inner_editor_title * { + margin: 0; +} + +#station_podcast .collapsible-header { + margin: 0 0 20px; + top: 20px; +} + +#station_podcast .dataTables_wrapper { + margin-left: 10px +} + +#station_podcast .dataTables_filter input { + width: 100%; +} + +.station_podcast_wrapper { + padding-right: 4px; + overflow-x: hidden; +} + +#station_podcast_help_text { + padding-top: 20px; + font-size: 14px; +} + +#podcast-settings label:nth-child(even) { + width: 100%; + text-align: left; +} + +#podcast-settings label > input { + width: auto; + margin: 6px 6px 0 25%; +} + +label { + text-align: right; + line-height: 26px; +} \ No newline at end of file diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index 3c2fc7117..4c8cc8199 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -4053,6 +4053,13 @@ li .ui-state-hover { float: left; } +.podcast-metadata-field { + display: inline-block; + width: 60%; + margin: 4px 0; + line-height: 24px; +} + .podcast_episodes_imported { text-align: center !important; } diff --git a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js index daade14ff..dc7b77cea 100644 --- a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js +++ b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js @@ -90,7 +90,7 @@ var AIRTIME = (function(AIRTIME) { emptyRow.hide(); var mediaType = parseInt($('.media_type_selector.selected').data('selection-id')), img = wrapper.find('.empty_placeholder_image'); - if (isNaN(mediaType)) { + if (!opts && isNaN(mediaType)) { return; } // Remove all classes for when we change between empty media types diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index ce86d8a9a..b42860b8e 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -1398,6 +1398,7 @@ var AIRTIME = (function(AIRTIME) { }; // Add a button to view the station podcast + /* Moved to a separate top-level menu item podcastToolbarButtons["StationPodcast"] = { title : $.i18n._("My Podcast"), iconClass : "icon-music", @@ -1408,6 +1409,7 @@ var AIRTIME = (function(AIRTIME) { }, validateConstraints: function () { return true; } }; + */ //Set up the div with id "podcast_table" as a datatable. mod.podcastTableWidget = new AIRTIME.widgets.Table( @@ -1581,6 +1583,8 @@ var AIRTIME = (function(AIRTIME) { // If we load sequentially there's a delay before the table appears aaData : {}, oColVis : { + buttonText: $.i18n._("Columns"), + iOverlayFade: 0, aiExclude: [0, 1, 2] }, oColReorder: { diff --git a/airtime_mvc/public/js/airtime/library/podcast.js b/airtime_mvc/public/js/airtime/library/podcast.js index ea4eb2b04..6bdc0331d 100644 --- a/airtime_mvc/public/js/airtime/library/podcast.js +++ b/airtime_mvc/public/js/airtime/library/podcast.js @@ -7,7 +7,7 @@ var AIRTIME = (function (AIRTIME) { mod = AIRTIME.podcast; - var endpoint = 'rest/podcast/', PodcastEpisodeTable, $stationPodcastTab; + var endpoint = '/rest/podcast/', PodcastEpisodeTable; /** * PodcastController constructor. @@ -23,7 +23,8 @@ var AIRTIME = (function (AIRTIME) { */ function PodcastController($scope, $http, podcast, tab) { // We need to pass in the tab object and the episodes table object so we can reference them - var self = this; + var self = this, + view = tab ? tab.contents : $(document); //We take a podcast object in as a parameter rather fetching the podcast by ID here because //when you're creating a new podcast, we already have the object from the result of the POST. We're saving @@ -31,7 +32,7 @@ var AIRTIME = (function (AIRTIME) { $scope.podcast = podcast; $scope.tab = tab; $scope.csrf = jQuery("#csrf").val(); - tab.contents.find("table").attr("id", "podcast_episodes_" + podcast.id); + view.find("table").attr("id", "podcast_episodes_" + podcast.id); /** * Save and update the podcast object. @@ -40,7 +41,7 @@ var AIRTIME = (function (AIRTIME) { $http.put(endpoint + $scope.podcast.id, {csrf_token: $scope.csrf, podcast: $scope.podcast}) .success(function () { AIRTIME.library.podcastDataTable.fnDraw(); - tab.close(); + tab || tab.close(); }); }; @@ -48,7 +49,7 @@ var AIRTIME = (function (AIRTIME) { * Close the tab and discard any changes made to the podcast data. */ $scope.discard = function () { - tab.close(); + tab || tab.close(); $scope.podcast = {}; }; @@ -95,35 +96,6 @@ var AIRTIME = (function (AIRTIME) { function StationPodcastController($scope, $http, podcast, tab) { // Super call to parent controller 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 - // Station Podcast button again - this way we don't have to go back to the server to get the ID. - $stationPodcastTab = tab; - - /** - * @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; } @@ -164,18 +136,6 @@ var AIRTIME = (function (AIRTIME) { StationPodcastController.prototype._initTable = function() { var self = this, $scope = this.$scope, buttons = { - editBtn: { - title : $.i18n._('Edit Metadata'), - iconClass : 'icon-pencil', - extraBtnClass : '', - elementId : '', - eventHandlers : { - click: self.openSelectedTabEditors.bind(self) - }, - validateConstraints: function () { - return this.getSelectedRows().length >= 1; - } - }, deleteBtn: { title : $.i18n._('Unpublish'), iconClass : 'icon-trash', @@ -187,8 +147,7 @@ var AIRTIME = (function (AIRTIME) { validateConstraints: function () { return this.getSelectedRows().length >= 1; } - }, - slideToggle: {} + } }, params = { sAjaxSource : endpoint + $scope.podcast.id + '/episodes', @@ -200,7 +159,7 @@ var AIRTIME = (function (AIRTIME) { }; this.episodeTable = AIRTIME.podcast.initPodcastEpisodeDatatable( - $scope.tab.contents.find('.podcast_episodes'), + $('.podcast_episodes'), params, buttons, { @@ -222,9 +181,7 @@ var AIRTIME = (function (AIRTIME) { * Initialize the Station podcast. */ StationPodcastController.prototype.initialize = function() { - PodcastController.prototype.initialize.call(this); // We want to override the default tab name behaviour and use "My Podcast" for clarity - this.$scope.tab.setName(jQuery.i18n._("My Podcast")); this._initTable(); }; @@ -242,7 +199,7 @@ var AIRTIME = (function (AIRTIME) { * * Bootstrapped for each podcast or Station podcast tab. */ - var podcastApp = angular.module('podcast', []) + mod.podcastApp = angular.module('podcast', []) .controller('Podcast', ['$scope', '$http', 'podcast', 'tab', PodcastController]) .controller('StationPodcast', ['$scope', '$http', 'podcast', 'tab', StationPodcastController]); @@ -285,8 +242,8 @@ var AIRTIME = (function (AIRTIME) { * @private */ function _bootstrapAngularApp(podcast, tab) { - podcastApp.value('podcast', podcast); - podcastApp.value('tab', tab); + mod.podcastApp.value('podcast', podcast); + mod.podcastApp.value('tab', tab); var wrapper = tab.contents.find(".angular_wrapper"); angular.bootstrap(wrapper.get(0), ["podcast"]); } @@ -481,19 +438,6 @@ var AIRTIME = (function (AIRTIME) { }); }; - /** - * Open a tab to view and edit the station podcast. - */ - mod.openStationPodcast = function () { - if (typeof $stationPodcastTab === 'undefined') { - $.get(endpoint + 'station', function(json) { - _initAppFromResponse(json); - }); - } else if ($stationPodcastTab != AIRTIME.tabs.getActiveTab()) { - $stationPodcastTab.switchTo(); - } - }; - /** * Create a bulk request to edit all currently selected podcasts. */ @@ -586,10 +530,12 @@ var AIRTIME = (function (AIRTIME) { { bDeferRender: true, oColVis: { + buttonText: $.i18n._("Columns"), + iOverlayFade: 0, aiExclude: [0, 1], - oColReorder: { - iFixedColumns: 1 // Checkbox - } + }, + oColReorder: { + iFixedColumns: 1 // Checkbox }, fnCreatedRow: function(nRow, aData, iDataIndex) { var self = this;