diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index fff58a7c8..08ff4618a 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -378,7 +378,6 @@ class LibraryController extends Zend_Controller_Action $this->view->form = $form; $this->view->id = $file_id; $this->view->title = $file->getPropelOrm()->getDbTrackTitle(); - $this->view->type = "md"; $this->view->html = $this->view->render('library/edit-file-md.phtml'); } diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index 59f1ec47b..c82940abe 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -456,7 +456,7 @@ var AIRTIME = (function(AIRTIME) { openTabObjectIds.each(function(i, el) { var v = parseInt($(el).val()); if ($.inArray(v, mediaIds) > -1) { - AIRTIME.tabs.closeTab($(el).closest(".pl-content").attr("data-tab-id")); + AIRTIME.tabs.get($(el).closest(".pl-content").attr("data-tab-id")).close(); } }); diff --git a/airtime_mvc/public/js/airtime/library/podcast.js b/airtime_mvc/public/js/airtime/library/podcast.js index 250680f37..b90e73465 100644 --- a/airtime_mvc/public/js/airtime/library/podcast.js +++ b/airtime_mvc/public/js/airtime/library/podcast.js @@ -13,13 +13,13 @@ var AIRTIME = (function (AIRTIME) { //AngularJS app var podcastApp = angular.module('podcast', []) - .controller('RestController', function($scope, $http, podcast) { + .controller('RestController', function($scope, $http, podcast, tab) { //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 //a roundtrip by not fetching it again here. $scope.podcast = podcast; - AIRTIME.tabs.setActiveTabName($scope.podcast.title); + tab.setName($scope.podcast.title); $scope.savePodcast = function() { $http.put(endpoint + $scope.podcast.id, { csrf_token: jQuery("#csrf").val(), podcast: $scope.podcast }) @@ -29,7 +29,7 @@ var AIRTIME = (function (AIRTIME) { }; $scope.discard = function() { - AIRTIME.tabs.getActiveTab().close(); + tab.close(); $scope.podcast = {}; }; }); @@ -46,9 +46,10 @@ var AIRTIME = (function (AIRTIME) { $.post(endpoint + "bulk", { csrf_token: $("#csrf").val(), method: method, ids: ids }, callback); } - function _bootstrapAngularApp(podcast) { + function _bootstrapAngularApp(podcast, tab) { podcastApp.value('podcast', JSON.parse(podcast)); - var wrapper = AIRTIME.tabs.getActiveTab().contents.find(".editor_pane_wrapper"); + podcastApp.value('tab', tab); + var wrapper = tab.contents.find(".editor_pane_wrapper"); wrapper.attr("ng-controller", "RestController"); angular.bootstrap(wrapper.get(0), ["podcast"]); } @@ -68,11 +69,10 @@ var AIRTIME = (function (AIRTIME) { mod.addPodcast = function() { $.post(endpoint, $("#podcast_url_dialog").find("form").serialize(), function(json) { - var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+json.id; - AIRTIME.tabs.openTab(json, uid); - _bootstrapAngularApp(json.podcast); + var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+json.id, + tab = AIRTIME.tabs.openTab(json, uid); + _bootstrapAngularApp(json.podcast, tab); $("#podcast_url_dialog").dialog("close"); - console.log(json); mod.initPodcastEpisodeDatatable(JSON.parse(json.podcast).episodes); }); }; @@ -80,9 +80,9 @@ var AIRTIME = (function (AIRTIME) { mod.editSelectedPodcasts = function() { _bulkAction("GET", function(json) { json.forEach(function(el) { - var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+el.id; - AIRTIME.tabs.openTab(el, uid, AIRTIME.podcast.init); - _bootstrapAngularApp(el.podcast); + var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+el.id, + tab = AIRTIME.tabs.openTab(el, uid, AIRTIME.podcast.init); + _bootstrapAngularApp(el.podcast, tab); mod.initPodcastEpisodeDatatable(JSON.parse(el.podcast).episodes); }); }); @@ -97,7 +97,6 @@ var AIRTIME = (function (AIRTIME) { }; mod.initPodcastEpisodeDatatable = function(episodes) { - console.log(episodes); var aoColumns = [ /* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "title" , "sClass" : "podcast_episodes_title" , "sWidth" : "170px" }, /* Author */ { "sTitle" : $.i18n._("Author") , "mDataProp" : "author" , "sClass" : "podcast_episodes_author" , "sWidth" : "170px" }, diff --git a/airtime_mvc/public/js/airtime/library/spl.js b/airtime_mvc/public/js/airtime/library/spl.js index 1197536b0..cdce25adb 100644 --- a/airtime_mvc/public/js/airtime/library/spl.js +++ b/airtime_mvc/public/js/airtime/library/spl.js @@ -381,7 +381,7 @@ var AIRTIME = (function(AIRTIME){ setCueEvents(); setFadeEvents(); mod.setModified(json.modified); - AIRTIME.tabs.setActiveTabName(json.name); + AIRTIME.tabs.getActiveTab().setName(json.name); AIRTIME.playlist.validatePlaylistElements(); redrawLib(); @@ -788,7 +788,7 @@ var AIRTIME = (function(AIRTIME){ setTimeout(function(){$status.fadeOut("slow", function(){$status.empty()})}, 5000); $pl.find(".title_obj_name").val(name); - AIRTIME.tabs.setActiveTabName(name); + AIRTIME.tabs.getActiveTab().setName(json.name); var $ws_id = $(".active-tab .obj_id"); $ws_id.attr("value", json.streamId); @@ -889,7 +889,7 @@ var AIRTIME = (function(AIRTIME){ } else { setTitleLabel(json.name); - AIRTIME.tabs.setActiveTabName(json.name); + AIRTIME.tabs.getActiveTab().setName(json.name); mod.setModified(json.modified); if (obj_type == "block") { @@ -1016,6 +1016,56 @@ var AIRTIME = (function(AIRTIME){ AIRTIME.playlist.validatePlaylistElements(); } + mod._initPlaylistTabEvents = function(newTab) { + newTab.assignTabClickHandler(function() { + if (!$(this).hasClass('active')) { + newTab.switchTo(); + $.post(baseUrl+'playlist/edit', { + format: "json", + id: newTab.pane.find(".obj_id").val(), + type: newTab.pane.find(".obj_type").val() + }); + } + }); + + mod.init(); + + // functions in smart_blockbuilder.js + setupUI(); + appendAddButton(); + appendModAddButton(); + removeButtonCheck(); + mod.setFadeIcon(); + }; + + mod._initFileMdEvents = function(newTab) { + newTab.contents.find(".md-cancel").on("click", function() { + newTab.close(); + }); + + newTab.contents.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(); + } + }); + + newTab.close(); + }); + + newTab.wrapper.find('#edit-md-dialog').on("keyup", function(event) { + if (event.keyCode === 13) { + newTab.wrapper.find('.md-save').click(); + } + }); + + mod.setupEventListeners(); + }; + mod.fnNew = function() { var url = baseUrl+'playlist/new'; @@ -1025,7 +1075,7 @@ var AIRTIME = (function(AIRTIME){ {format: "json", type: 'playlist'}, function(json) { var uid = AIRTIME.library.MediaTypeStringEnum.PLAYLIST+"_"+json.id; - AIRTIME.tabs.openPlaylistTab(json, uid); + AIRTIME.tabs.openTab(json, uid, AIRTIME.playlist._initPlaylistTabEvents); redrawLib(); }); }; @@ -1039,7 +1089,7 @@ var AIRTIME = (function(AIRTIME){ {format: "json"}, function(json) { var uid = AIRTIME.library.MediaTypeStringEnum.WEBSTREAM+"_"+json.id; - AIRTIME.tabs.openPlaylistTab(json, uid); + AIRTIME.tabs.openTab(json, uid, AIRTIME.playlist._initPlaylistTabEvents); redrawLib(); }); }; @@ -1054,13 +1104,13 @@ var AIRTIME = (function(AIRTIME){ {format: "json", type: 'block'}, function(json){ var uid = AIRTIME.library.MediaTypeStringEnum.BLOCK+"_"+json.id; - AIRTIME.tabs.openPlaylistTab(json, uid); + AIRTIME.tabs.openTab(json, uid, AIRTIME.playlist._initPlaylistTabEvents); redrawLib(); }); }; mod.fileMdEdit = function(json, uid) { - AIRTIME.tabs.openFileMdEditorTab(json, uid); + AIRTIME.tabs.openTab(json, uid, AIRTIME.playlist._initFileMdEvents); }; mod.fnEdit = function(id, type, url) { @@ -1071,7 +1121,7 @@ var AIRTIME = (function(AIRTIME){ {format: "json", id: id, type: type}, function(json) { var uid = AIRTIME.library.MediaTypeFullToStringEnum.type+"_"+id; - AIRTIME.tabs.openPlaylistTab(json, uid); + AIRTIME.tabs.openTab(json, uid, AIRTIME.playlist._initPlaylistTabEvents); redrawLib(); }); }; @@ -1107,7 +1157,7 @@ var AIRTIME = (function(AIRTIME){ {format: "json", ids: id, modified: lastMod, type: type}, function(json){ var uid = AIRTIME.library.MediaTypeStringEnum.WEBSTREAM+"_"+id; - AIRTIME.tabs.openPlaylistTab(json, uid); + AIRTIME.tabs.openTab(json, uid, AIRTIME.playlist._initPlaylistTabEvents); redrawLib(); }); }; @@ -1155,7 +1205,7 @@ var AIRTIME = (function(AIRTIME){ mod.replaceForm = function(json){ $pl.find('.editor_pane_wrapper').html(json.html); var uid = AIRTIME.library.MediaTypeStringEnum.BLOCK+"_"+json.id; - AIRTIME.tabs.openPlaylistTab(json, uid); + AIRTIME.tabs.openTab(json, uid, AIRTIME.playlist._initPlaylistTabEvents); }; @@ -1432,6 +1482,10 @@ var AIRTIME = (function(AIRTIME){ mod.setCurrent = function(pl) { $pl = pl; + $.post(baseUrl + "playlist/change-playlist", { + "id": mod.getId($pl), + "type": $pl.find('.obj_type').val() + }); }; mod.init = function() { @@ -1485,16 +1539,8 @@ var AIRTIME = (function(AIRTIME){ AIRTIME.playlist.init(); }; - mod.onResize = function() { - var h = $(".panel-header .nav").height(); - $(".pl-content").css("margin-top", h + 5); // 8px extra for padding - $("#show_builder_table_wrapper").css("top", h + 5); - }; - return AIRTIME; }(AIRTIME || {})); - $(document).ready(AIRTIME.playlist.onReady); -$(window).resize(AIRTIME.playlist.onResize); diff --git a/airtime_mvc/public/js/airtime/showbuilder/tabs.js b/airtime_mvc/public/js/airtime/showbuilder/tabs.js index e205e9975..3e6ef9e67 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/tabs.js +++ b/airtime_mvc/public/js/airtime/showbuilder/tabs.js @@ -1,9 +1,40 @@ var AIRTIME = (function(AIRTIME){ + /** + * AIRTIME module namespace object + */ var mod, + /** + * Tab counter to use as unique tab IDs that can be + * retrieved from the DOM + * + * @type {number} + */ $tabCount = 0, + /** + * Map of Tab IDs (by tabCount) to object UIDs so + * Tabs can be referenced either by ID (from the DOM) + * or by UID (from object data) + * + * @type {{}} + */ $tabMap = {}, + /** + * Map of object UIDs to currently open Tab objects + * + * @type {{}} + */ $openTabs = {}, + /** + * The currently active (open) Tab object + * + * @type {Tab} + */ $activeTab, + /** + * Singleton object used to reference the schedule tab + * + * @type {ScheduleTab} + */ $scheduleTab; if (AIRTIME.tabs === undefined) { @@ -12,9 +43,22 @@ var AIRTIME = (function(AIRTIME){ mod = AIRTIME.tabs; /* ##################################################### - Internal Functions + Object Initialization and Functions ##################################################### */ + /** + * Tab object constructor + * + * @param {{}} json a javascript object of the form + * { + * 'html': the HTML to render as the tab contents + * } + * @param {string} uid the unique ID for the tab. Uses the values in + * AIRTIME.library.MediaTypeStringEnum and the object ID + * to create a string of the form TYPE_ID. + * @returns {Tab} the created Tab object + * @constructor + */ var Tab = function(json, uid) { var self = this; @@ -28,17 +72,18 @@ var AIRTIME = (function(AIRTIME){ self.id = ++$tabCount; self.uid = uid; - var wrapper = "