diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index 7bad3225e..3402a7a61 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -11,6 +11,7 @@ class LibraryController extends Zend_Controller_Action $ajaxContext = $this->_helper->getHelper('AjaxContext'); $ajaxContext->addActionContext('contents', 'json') ->addActionContext('delete', 'json') + ->addActionContext('delete-group', 'json') ->addActionContext('context-menu', 'json') ->addActionContext('get-file-meta-data', 'html') ->addActionContext('upload-file-soundcloud', 'json') @@ -178,6 +179,45 @@ class LibraryController extends Zend_Controller_Action $this->view->id = $id; } } + + public function deleteGroupAction() + { + $ids = $this->_getParam('ids'); + $userInfo = Zend_Auth::getInstance()->getStorage()->read(); + $user = new Application_Model_User($userInfo->id); + + if ($user->isAdmin()) { + + if (!is_null($ids)) { + foreach ($ids as $key => $id) { + $file = Application_Model_StoredFile::Recall($id); + + if (PEAR::isError($file)) { + $this->view->message = $file->getMessage(); + return; + } + else if(is_null($file)) { + $this->view->message = "file doesn't exist"; + return; + } + + $res = $file->delete(); + + if (PEAR::isError($res)) { + $this->view->message = $res->getMessage(); + return; + } + else { + $res = settype($res, "integer"); + $data = array("filepath" => $file->getFilePath(), "delete" => $res); + Application_Model_RabbitMq::SendMessageToMediaMonitor("file_delete", $data); + } + } + + $this->view->ids = $ids; + } + } + } public function contentsAction() { diff --git a/airtime_mvc/application/controllers/PlaylistController.php b/airtime_mvc/application/controllers/PlaylistController.php index 9c3bc11ec..7618d94c9 100644 --- a/airtime_mvc/application/controllers/PlaylistController.php +++ b/airtime_mvc/application/controllers/PlaylistController.php @@ -8,18 +8,20 @@ class PlaylistController extends Zend_Controller_Action { $ajaxContext = $this->_helper->getHelper('AjaxContext'); $ajaxContext->addActionContext('add-item', 'json') - ->addActionContext('delete-item', 'json') - ->addActionContext('set-fade', 'json') - ->addActionContext('set-cue', 'json') - ->addActionContext('move-item', 'json') - ->addActionContext('close', 'json') - ->addActionContext('new', 'json') - ->addActionContext('edit', 'json') - ->addActionContext('delete-active', 'json') - ->addActionContext('delete', 'json') + ->addActionContext('delete-item', 'json') + ->addActionContext('add-group', 'json') + ->addActionContext('delete-group', 'json') + ->addActionContext('set-fade', 'json') + ->addActionContext('set-cue', 'json') + ->addActionContext('move-item', 'json') + ->addActionContext('close', 'json') + ->addActionContext('new', 'json') + ->addActionContext('edit', 'json') + ->addActionContext('delete-active', 'json') + ->addActionContext('delete', 'json') ->addActionContext('set-playlist-fades', 'json') ->addActionContext('set-playlist-name', 'json') - ->addActionContext('set-playlist-description', 'json') + ->addActionContext('set-playlist-description', 'json') ->initContext(); $this->pl_sess = new Zend_Session_Namespace(UI_PLAYLIST_SESSNAME); @@ -209,6 +211,59 @@ class PlaylistController extends Zend_Controller_Action unset($this->view->pl); } + public function addGroupAction() + { + $ids = $this->_getParam('ids'); + $pos = $this->_getParam('pos', null); + + if (!is_null($ids)) { + $pl = $this->getPlaylist(); + if ($pl === false) { + $this->view->playlist_error = true; + return false; + } + + foreach ($ids as $key => $value) { + $res = $pl->addAudioClip($value); + if (PEAR::isError($res)) { + $this->view->message = $res->getMessage(); + break; + } + } + + $this->view->pl = $pl; + $this->view->html = $this->view->render('playlist/update.phtml'); + $this->view->name = $pl->getName(); + $this->view->length = $pl->getLength(); + $this->view->description = $pl->getDescription(); + return; + } + $this->view->message = "a file is not chosen"; + } + + public function deleteGroupAction() + { + $ids = $this->_getParam('ids', null); + + foreach ($ids as $key => $id) { + $pl = Application_Model_Playlist::Recall($id); + + if ($pl !== FALSE) { + Application_Model_Playlist::Delete($id); + $pl_sess = $this->pl_sess; + if($pl_sess->id === $id){ + unset($pl_sess->id); + } + } else { + $this->view->playlist_error = true; + return false; + } + } + + $this->view->ids = $ids; + $this->view->html = $this->view->render('playlist/index.phtml'); + } + public function setCueAction() { $pos = $this->_getParam('pos'); diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index 7b95307f7..7dc2ece42 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -607,10 +607,10 @@ dl.inline-list dd { } .dataTables_filter input { background: url("images/search_auto_bg.png") no-repeat scroll 0 0 #DDDDDD; - width: 60%; - border: 1px solid #5B5B5B; - margin: 0; - padding: 4px 3px 4px 25px; + width: 60%; + border: 1px solid #5B5B5B; + margin-left: -8px; + padding: 4px 3px 4px 25px; } .dataTables_length select { background-color: #DDDDDD; @@ -623,6 +623,15 @@ dl.inline-list dd { vertical-align: top; } +.library_toolbar .ui-button { + float: right; + text-align:center; + font-size:12px; + font-weight:normal; + padding: 0.2em 1em; + margin: 0.5em 0.2em; +} + /*----END Data Table----*/ fieldset { diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index 88fc6a9aa..c3b6279e2 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -1,4 +1,5 @@ var dTable; +var checkedCount = 0; //used by jjmenu function getId() { @@ -32,8 +33,20 @@ function deleteAudioClip(json) { return; } - deleteItem("au", json.id); + if (json.ids != undefined) { + for (var i = json.ids.length - 1; i >= 0; i--) { + deleteItem("au", json.ids[i]); + } + } else if (json.id != undefined) { + deleteItem("au", json.id); + } location.reload(true); +} + +function confirmDeleteGroup() { + if(confirm('Are you sure you want to delete the selected items?')){ + groupDelete(); + } } //callbacks called by jjmenu @@ -75,11 +88,17 @@ function checkImportStatus(){ function deletePlaylist(json) { if(json.message) { - alert(json.message); - return; + alert(json.message); + return; } - - deleteItem("pl", json.id); + + if (json.ids != undefined) { + for (var i = json.ids.length - 1; i >= 0; i--) { + deleteItem("pl", json.ids[i]); + } + } else if (json.id != undefined) { + deleteItem("pl", json.id); + } window.location.reload(); } //end callbacks called by jjmenu @@ -92,7 +111,7 @@ function addLibraryItemEvents() { cursor: 'pointer' }); - $('#library_display tbody tr td').not('[class=datatable_checkbox]') + $('#library_display tbody tr td').not('[class=library_checkbox]') .jjmenu("click", [{get:"/Library/context-menu/format/json/id/#id#/type/#type#"}], {id: getId, type: getType}, @@ -105,36 +124,34 @@ function dtRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { type = aData["ftype"].substring(0,2); id = aData["id"]; - + if(type == "au") { - $('td:eq(6)', nRow).html( '' ); - } - else if(type == "pl") { - $('td:eq(6)', nRow).html( '' ); + $('td.library_type', nRow).html( '' ); + } else if(type == "pl") { + $('td.library_type', nRow).html( '' ); } - $(nRow).attr("id", type+'_'+id); + $(nRow).attr("id", type+'_'+id); - // insert id on lenth field - $('td:eq(5)', nRow).attr("id", "length"); + // insert id on lenth field + $('td.library_length', nRow).attr("id", "length"); - return nRow; + return nRow; } function dtDrawCallback() { - addLibraryItemEvents(); - addMetadataQtip(); - saveNumEntriesSetting(); - var temp = dTable.fnGetData() - console.log(temp) + addLibraryItemEvents(); + addMetadataQtip(); + saveNumEntriesSetting(); + setupGroupActions(); } function addProgressIcon(id) { - if($("#au_"+id).find("td:eq(0)").find("span").length > 0){ - $("#au_"+id).find("td:eq(0)").find("span").removeClass(); + if($("#au_"+id).find("td.library_title").find("span").length > 0){ + $("#au_"+id).find("td.library_title").find("span").removeClass(); $("span[id="+id+"]").addClass("small-icon progress"); }else{ - $("#au_"+id).find("td:eq(0)").append('') + $("#au_"+id).find("td.library_title").append('') } } @@ -233,7 +250,7 @@ function addQtipToSCIcons(){ function addMetadataQtip(){ var tableRow = $('#library_display tbody tr'); tableRow.each(function(){ - var title = $(this).find('td:eq(0)').html() + var title = $(this).find('td.library_title').html() var info = $(this).attr("id") info = info.split("_"); var id = info[1]; @@ -301,6 +318,133 @@ function getNumEntriesPreference(data) { return parseInt(data.libraryInit.numEntries); } +function groupAdd() { + var ids = new Array(); + var addGroupUrl = '/Playlist/add-group'; + var newSPLUrl = '/Playlist/new/format/json'; + var dirty = true; + $('#library_display tbody tr').each(function() { + var idSplit = $(this).attr('id').split("_"); + var id = idSplit.pop(); + var type = idSplit.pop(); + if (dirty && $(this).find(":checkbox").attr("checked")) { + if (type == "au") { + ids.push(id); + } else if (type == "pl") { + alert("Can't add playlist to another playlist"); + dirty = false; + } + } + }); + + if (dirty && ids.length > 0) { + stopAudioPreview(); + + if ($('#spl_sortable').length == 0) { + $.post(newSPLUrl, function(json) { + openDiffSPL(json); + redrawDataTablePage(); + + $.post(addGroupUrl, {format: "json", ids: ids}, setSPLContent); + }); + } else { + $.post(addGroupUrl, {format: "json", ids: ids}, setSPLContent); + } + } +} + +function groupDelete() { + var auIds = new Array(); + var plIds = new Array(); + var auUrl = '/Library/delete-group'; + var plUrl = '/Playlist/delete-group'; + var dirty = true; + $('#library_display tbody tr').each(function() { + var idSplit = $(this).attr('id').split("_"); + var id = idSplit.pop(); + var type = idSplit.pop(); + if (dirty && $(this).find(":checkbox").attr("checked")) { + if (type == "au") { + auIds.push(id); + } else if (type == "pl") { + plIds.push(id); + } + } + }); + + if (dirty && (auIds.length > 0 || plIds.length > 0)) { + stopAudioPreview(); + + if (auIds.length > 0) { + $.post(auUrl, {format: "json", ids: auIds}, deleteAudioClip); + } + if (plIds.length > 0) { + $.post(plUrl, {format: "json", ids: plIds}, deletePlaylist); + } + } +} + +function toggleAll() { + var checked = $(this).attr("checked"); + $('#library_display tr').each(function() { + $(this).find(":checkbox").attr("checked", checked); + if (checked) { + $(this).addClass('selected'); + } else { + $(this).removeClass('selected'); + } + }); + + if (checked) { + checkedCount = $('#library_display tbody tr').size(); + } else { + checkedCount = 0; + } +} + +function checkBoxChanged() { + var cbAll = $('#library_display thead').find(":checkbox"); + var cbAllChecked = cbAll.attr("checked"); + var checked = $(this).attr("checked"); + var size = $('#library_display tbody tr').size(); + if (checked) { + if (checkedCount < size) { + checkedCount++; + } + $(this).parent().parent().addClass('selected'); + } else { + if (!checked && checkedCount > 0) { + checkedCount--; + } + $(this).parent().parent().removeClass('selected'); + } + + if (cbAllChecked && checkedCount < size) { + cbAll.attr("checked", false); + } else if (!cbAllChecked && checkedCount == size) { + cbAll.attr("checked", true); + } + + +} + +function setupGroupActions() { + checkedCount = 0; + $('#library_display tr:nth-child(1)').find(":checkbox").attr("checked", false); + $('#library_display thead').find(":checkbox").change(toggleAll); + $('#library_display tbody tr').each(function() { + $(this).find(":checkbox").change(checkBoxChanged); + }); +} + +function fnShowHide(iCol) { + /* Get the DataTables object again - this is not a recreation, just a get of the object */ + var oTable = dTable; + + var bVis = oTable.fnSettings().aoColumns[iCol].bVisible; + oTable.fnSetColumnVis( iCol, bVis ? false : true ); +} + function createDataTable(data) { dTable = $('#library_display').dataTable( { "bProcessing": true, @@ -318,14 +462,14 @@ function createDataTable(data) { "fnRowCallback": dtRowCallback, "fnDrawCallback": dtDrawCallback, "aoColumns": [ - /* Checkbox */ { "sTitle": "", "bSortable": false, "bSearchable": false, "mDataProp": "checkbox", "sWidth": "25px", "sClass": "datatable_checkbox" }, - /* Id */ { "sName": "id", "bSearchable": false, "bVisible": false, "mDataProp": "id" }, - /* Title */ { "sTitle": "Title", "sName": "track_title", "mDataProp": "track_title" }, - /* Creator */ { "sTitle": "Creator", "sName": "artist_name", "mDataProp": "artist_name" }, - /* Album */ { "sTitle": "Album", "sName": "album_title", "mDataProp": "album_title" }, - /* Genre */ { "sTitle": "Genre", "sName": "genre", "mDataProp": "genre" }, - /* Length */ { "sTitle": "Length", "sName": "length", "mDataProp": "length" }, - /* Type */ { "sTitle": "Type", "sName": "ftype", "bSearchable": false, "mDataProp": "ftype", "sWidth": "50px" }, + /* Checkbox */ { "sTitle": "", "bSortable": false, "bSearchable": false, "mDataProp": "checkbox", "sWidth": "25px", "sClass": "library_checkbox"}, + /* Id */ { "sName": "id", "bSearchable": false, "bVisible": false, "mDataProp": "id", "sClass": "library_id"}, + /* Title */ { "sTitle": "Title", "sName": "track_title", "mDataProp": "track_title", "sClass": "library_title"}, + /* Creator */ { "sTitle": "Creator", "sName": "artist_name", "mDataProp": "artist_name", "sClass": "library_creator"}, + /* Album */ { "sTitle": "Album", "sName": "album_title", "mDataProp": "album_title", "sClass": "library_album"}, + /* Genre */ { "sTitle": "Genre", "sName": "genre", "mDataProp": "genre", "sClass": "library_genre"}, + /* Length */ { "sTitle": "Length", "sName": "length", "mDataProp": "length", "sWidth": "15%", "sClass": "library_length"}, + /* Type */ { "sTitle": "Type", "sName": "ftype", "bSearchable": false, "mDataProp": "ftype", "sWidth": "7%", "sClass": "library_type"}, ], "aaSorting": [[2,'asc']], "sPaginationType": "full_numbers", @@ -335,9 +479,16 @@ function createDataTable(data) { "sSearch": "" }, "iDisplayLength": getNumEntriesPreference(data), - "bStateSave": true + "bStateSave": true, + "sDom": 'lfr<"H"C<"library_toolbar">>t<"F"ip>' }); dTable.fnSetFilteringDelay(350); + + + $("div.library_toolbar").html('Delete' + + 'Add'); + $('#library_group_add').click(groupAdd); + $('#library_group_delete').click(confirmDeleteGroup); } $(document).ready(function() { @@ -346,7 +497,7 @@ $(document).ready(function() { $.ajax({ url: "/Api/library-init/format/json", dataType:"json", success:createDataTable, error:function(jqXHR, textStatus, errorThrown){}}); - checkImportStatus() + checkImportStatus(); setInterval( "checkImportStatus()", 5000 ); setInterval( "checkSCUploadStatus()", 5000 );