From 0199f572bd3d71c4741133bbc403f049536c8465 Mon Sep 17 00:00:00 2001 From: Naomi Aro Date: Thu, 2 Feb 2012 15:51:15 +0100 Subject: [PATCH] CC-3174 : showbuilder dragging into timeline is working need to replace jjmenus --- .../controllers/LibraryController.php | 61 +-- .../library/events/library_playlistbuilder.js | 12 + .../library/events/library_showbuilder.js | 9 +- .../public/js/airtime/library/library.js | 22 - .../public/js/airtime/showbuilder/builder.js | 97 +++-- .../js/contextmenu/jjmenu-modified(fix).js | 377 ++++++++++++++++++ airtime_mvc/public/js/contextmenu/jjmenu.js | 18 +- 7 files changed, 473 insertions(+), 123 deletions(-) create mode 100644 airtime_mvc/public/js/contextmenu/jjmenu-modified(fix).js diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index a3bd1d678..e1bc4fa9e 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -85,73 +85,48 @@ class LibraryController extends Zend_Controller_Action $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - $pl_sess = $this->pl_sess; + if ($type === "audioclip") { - if($type === "au") { - - if(isset($pl_sess->id)) { - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/add-item'.$params, 'callback' => 'window["setSPLContent"]'), - 'title' => 'Add to Playlist'); - } + $file = Application_Model_StoredFile::Recall($id); $menu[] = array('action' => array('type' => 'gourl', 'url' => '/Library/edit-file-md/id/#id#'), 'title' => 'Edit Metadata'); - // added for downlaod - $id = $this->_getParam('id'); - - $file_id = $this->_getParam('id', null); - $file = Application_Model_StoredFile::Recall($file_id); - $url = $file->getRelativeFileUrl($baseUrl).'/download/true'; $menu[] = array('action' => array('type' => 'gourl', 'url' => $url), 'title' => 'Download'); if (Application_Model_Preference::GetUploadToSoundcloudOption()) { - $text = "Upload to SoundCloud"; - if(!is_null($file->getSoundCloudId())){ - $text = "Re-upload to SoundCloud"; - } - $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Library/upload-file-soundcloud/id/#id#', - 'callback'=>"window['addProgressIcon']('$file_id')"),'title' => $text); $scid = $file->getSoundCloudId(); - if($scid > 0){ + if (!is_null($scid)){ + $text = "Re-upload to SoundCloud"; + } + else { + $text = "Upload to SoundCloud"; + } + + $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Library/upload-file-soundcloud/id/#id#', + 'callback'=>"window['addProgressIcon']('$file_id')"),'title' => $text); + + + if ($scid > 0){ $link_to_file = $file->getSoundCloudLinkToFile(); - $menu[] = array('action' => array('type' => 'fn', - 'callback' => "window['openFileOnSoundCloud']('$link_to_file')"), - 'title' => 'View on SoundCloud'); + $menu[] = array('action' => array('type' => 'gourl', 'url' => $link_to_file, 'target' => '_blank'), + 'title' => 'View on Soundcloud'); } } - - if ($user->isAdmin()) { - $menu[] = array('action' => array('type' => 'fn', - 'callback' => "window['confirmDeleteAudioClip']('$paramsPop')"), - 'title' => 'Delete'); - } } - else if($type === "pl") { + else if ($type === "playlist") { - if(!isset($pl_sess->id) || $pl_sess->id !== $id) { + if (!isset($this->pl_sess->id) || $this->pl_sess->id !== $id) { $menu[] = array('action' => array('type' => 'ajax', 'url' => '/Playlist/edit'.$params, 'callback' => 'window["openDiffSPL"]'), 'title' => 'Edit'); } - else if(isset($pl_sess->id) && $pl_sess->id === $id) { - $menu[] = array('action' => - array('type' => 'ajax', - 'url' => '/Playlist/close'.$params, - 'callback' => 'window["noOpenPL"]'), - 'title' => 'Close'); - } - - $menu[] = array('action' => array('type' => 'fn', - 'callback' => "window['confirmDeletePlaylist']('$paramsPop')"), - 'title' => 'Delete'); - } //returns format jjmenu is looking for. diff --git a/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js b/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js index 81a8516b7..5c273e3d0 100644 --- a/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js +++ b/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js @@ -1,6 +1,18 @@ function fnLibraryTableRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + function test() { + alert("hi"); + } + $(nRow).attr("id", aData["tr_id"]); + + $(nRow).find('td') + .jjmenu("rightClick", + [{get:"/Library/context-menu/format/json/id/#id#/type/#type#"}], + {id: aData["id"], type: aData["ftype"]}, + {xposition: "mouse", yposition: "mouse"}); + + //{title:"Menu Item 4 - Js function", action:{type:"fn",callback:function(){ alert('THIS IS THE TEST'); } return nRow; } 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 dbb5a2c73..a798ab18a 100644 --- a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js +++ b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js @@ -1,8 +1,11 @@ function fnLibraryTableRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { - - $(nRow).attr("id", aData["tr_id"]); + var jRow = $(nRow); + + jRow.attr("id", aData["tr_id"]); + jRow.addClass("lib-sb"); - $(nRow).data("show_builder", {"id": aData["id"], "length": aData["length"]}); + //save some info for reordering purposes. + jRow.data({"aData": aData}); return nRow; } diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index 11bb42f27..6b391cf9b 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -1,21 +1,3 @@ -//used by jjmenu -/* -function getId() { - var tr_id = $(this.triggerElement).parent().attr("id"); - tr_id = tr_id.split("_"); - - return tr_id[1]; -} - -function getType() { - var tr_id = $(this.triggerElement).parent().attr("id"); - tr_id = tr_id.split("_"); - - return tr_id[0]; -} -*/ -//end functions used by jjmenu - function addToolBarButtonsLibrary(aButtons) { var i, length = aButtons.length, @@ -88,10 +70,6 @@ function confirmDeleteGroup() { } } -function openFileOnSoundCloud(link){ - window.open(link); -} - function checkImportStatus(){ $.getJSON('/Preference/is-import-in-progress', function(data){ var div = $('#import_status'); diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index f27a560a8..2292d32b5 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -121,7 +121,7 @@ $(document).ready(function() { node; //save some info for reordering purposes. - $(nRow).data({aData: aData}); + $(nRow).data({"aData": aData}); fnPrepareSeparatorRow = function(sRowContent, sClass) { @@ -142,7 +142,7 @@ $(document).ready(function() { node.innerHTML = ''; sSeparatorHTML = ''+aData.title+''+aData.starts+''+aData.ends+''; - fnPrepareSeparatorRow(sSeparatorHTML, "show-builder-header"); + fnPrepareSeparatorRow(sSeparatorHTML, "sb-header"); } else if (aData.footer === true) { @@ -150,7 +150,7 @@ $(document).ready(function() { node.innerHTML = ''; sSeparatorHTML = 'Show Footer'; - fnPrepareSeparatorRow(sSeparatorHTML, "show-builder-footer"); + fnPrepareSeparatorRow(sSeparatorHTML, "sb-footer"); } else if (aData.empty === true) { @@ -158,7 +158,7 @@ $(document).ready(function() { node.innerHTML = ''; sSeparatorHTML = 'Show Empty'; - fnPrepareSeparatorRow(sSeparatorHTML, "show-builder-empty odd"); + fnPrepareSeparatorRow(sSeparatorHTML, "sb-empty odd"); } else { $(nRow).attr("id", "sched_"+aData.id); @@ -170,7 +170,7 @@ $(document).ready(function() { else { node.innerHTML = ''; - $(nRow).addClass("show-builder-not-allowed"); + $(nRow).addClass("sb-not-allowed"); } } @@ -241,9 +241,9 @@ $(document).ready(function() { "fnPreRowSelect": function ( e ) { var node = e.currentTarget; //don't select separating rows, or shows without privileges. - if ($(node).hasClass("show-builder-header") - || $(node).hasClass("show-builder-footer") - || $(node).hasClass("show-builder-not-allowed")){ + if ($(node).hasClass("sb-header") + || $(node).hasClass("sb-footer") + || $(node).hasClass("sb-not-allowed")){ return false; } return true; @@ -283,7 +283,7 @@ $(document).ready(function() { if ($(this).is(":checked")) { var allowedNodes; - allowedNodes = oTable.find('tr:not(.show-builder-header):not(.show-builder-footer):not(.show-builder-not-allowed)'); + allowedNodes = oTable.find('tr:not(.sb-header):not(.sb-footer):not(.sb-not-allowed)'); allowedNodes.each(function(i, el){ oTT.fnSelect(el); @@ -315,43 +315,60 @@ $(document).ready(function() { oTable.fnDraw(); }); - tableDiv.sortable({ - placeholder: "placeholder show-builder-placeholder", - forceHelperSize: true, - forcePlaceholderSize: true, - items: 'tr:not(:first):not(.show-builder-header):not(.show-builder-footer):not(.show-builder-not-allowed):not(.show-builder-empty)', - //cancel: ".show-builder-header .show-builder-footer", - receive: function(event, ui) { - var x; - }, - update: function(event, ui) { - var oItemData = ui.item.data("aData"), - oPrevData = ui.item.prev().data("aData"), - oRequestData = {format: "json"}; + var sortableConf = (function(){ + var origRow, + oItemData, + oPrevData, + fnAdd, + fnMove, + fnReceive, + fnUpdate; + + fnAdd = function() { + var aSchedIds = [], + aMediaIds = []; - //if prev item is a footer, item is not scheduled into a show. - if (oPrevData.footer === false) { - oRequestData.instance = oPrevData.instance; - } + aSchedIds.push({"id": oPrevData.id, "instance": oPrevData.instance}); + aMediaIds.push({"id": oItemData.id, "type": oItemData.ftype}); + + $.post("/showbuilder/schedule-add", + {"format": "json", "mediaIds": aMediaIds, "schedIds": aSchedIds}, + function(json){ + oTable.fnDraw(); + }); + }; + + fnReceive = function(event, ui) { + origRow = ui.item; + }; + + fnUpdate = function(event, ui) { + oPrevData = ui.item.prev().data("aData"); - //set the start time appropriately - if (oPrevData.header === true) { - oRequestData.start = oPrevData.startsUnix; + //item was dragged in + if (origRow !== undefined) { + oItemData = origRow.data("aData"); + fnAdd(); } + //item was reordered. else { - oRequestData.start = oPrevData.endsUnix; + oItemData = ui.item.data("aData"); } - oRequestData.id = oItemData.id; - oRequestData.duration = oItemData.duration; - - /* - $.post("/showbuilder/schedule", oRequestData, function(json){ - var x; - }); - */ - } - }); + origRow = undefined; + }; + + return { + placeholder: "placeholder show-builder-placeholder", + forceHelperSize: true, + forcePlaceholderSize: true, + items: 'tr:not(:first):not(.sb-header):not(.sb-footer):not(.sb-not-allowed):not(.sb-empty)', + receive: fnReceive, + update: fnUpdate + }; + }()); + + tableDiv.sortable(sortableConf); $("#show_builder_toolbar") .append('') diff --git a/airtime_mvc/public/js/contextmenu/jjmenu-modified(fix).js b/airtime_mvc/public/js/contextmenu/jjmenu-modified(fix).js new file mode 100644 index 000000000..915377217 --- /dev/null +++ b/airtime_mvc/public/js/contextmenu/jjmenu-modified(fix).js @@ -0,0 +1,377 @@ +/* jjmenu - context menu jquery plugin + * http://jursza.net/dev/jjmenu/ + * + * @author Jacek Jursza (okhan.pl@gmail.com) + * @version 1.1.2 + * @date 2010-08-28 + * @category jQuery plugin + * @copyright (c) 2009 Jacek Jursza (http://jursza.net/) + * @licence MIT [http://www.opensource.org/licenses/mit-license.php] + */ + +(function($){ + + $.fn.jjmenu = function (clickEvent, param, myReplaces, effect) { + + var global = this; + var acceptEvent = false; + + + if ( clickEvent == "rightClick" || clickEvent == "both" ) + { + global.mousedown(function(event) { + if (event.button == 2 && (clickEvent == "rightClick" || clickEvent == "both")) { // right click + global.pageX = event.pageX; + global.pageY = event.pageY; + event.preventDefault(); + event.stopPropagation(); + var mmain = new menu("main", param, myReplaces, this, effect); + $(this)[0].oncontextmenu = function() { + return false; + } + $(this).unbind('mouseup'); + $(this).blur(); + return false; + } + }); + + document.body.oncontextmenu = function() { + if ($("div[id^=jjmenu_main]").length) return false; + } + } + + if ( clickEvent == "click" || clickEvent == "both" ) + { + global.click( + function(event) { + if (this == event.currentTarget) { + global.pageX = event.pageX; + global.pageY = event.pageY; + event.preventDefault(); + event.stopPropagation(); + var mmain = new menu("main", param, myReplaces, this, effect); + $(this).blur(); + return false; + } + }); + } + + $(document).click(function(event) { if (event.button!=2) $("div[id^=jjmenu]").remove(); }); + + /* Menu obeject */ + function menu(id,param,myReplaces,el,effect) { + + var effect = getEffect(id, effect); + + if (id == "main") window.triggerElement = el; + $("div[id^=jjmenu_"+id+"]").remove(); + + var m = document.createElement('div'); + var ms = document.createElement('span'); + $(m).append(ms); + + m.className = "jjmenu"; m.id = "jjmenu_"+id; + $(m).css({display:'none'}); + $(document.body).append(m); + + positionMenu(); + + var dynamicItems = false; + + for (var i in param) { + + if (param[i].get) { + + dynamicItems = true; + $.getJSON(uReplace(param[i].get), function(data) { + /* jjmenu doesn't provide ability to add callback function + in case of error. So the error handling has to be included in + the library itself */ + if(data.show_error == true){ + alert("The show instance doesn't exist anymore!"); + window.location.reload(); + }else if(data.playlist_error == true){ + alert("The playlist doesn't exist anymore!"); + window.location.reload(); + } + for (var ii in data) { + putItem(data[ii]); + } + checkPosition(); + }) + $(this).ajaxError( function() { + checkPosition(); + }); + } + else if (param[i].getByFunction) { + + if (typeof(param[i].getByFunction) == "function") { + var uF = param[i].getByFunction; + } + else { + var uF = eval(param[i].getByFunction); + } + var uItems = uF(myReplaces); + for (var ii in uItems) { + putItem(uItems[ii]); + } + checkPosition(); + } + else { + putItem(param[i]); + } + } + + if (!dynamicItems) checkPosition(); + showMenu(); + + /* first position menu */ + function positionMenu() { + + var pos = $(el).offset(); + + var t = pos.top; + + if (effect.xposition == "left") { + var l = pos.left; + } + else { + var l = pos.left+$(el).width()+10; + } + + if (effect.xposition == "mouse") { + l = global.pageX; + } + if (effect.yposition == "mouse") { + t = global.pageY; + } + + $(m).css({position:"absolute",top:t+"px",left:l+"px"}); + } + + /* correct menu position */ + function checkPosition() { + + var isHidden = $(m).css("display") == "none" ? true : false; + var noAuto = false; + + if (effect.orientation == "top" || effect.orientation == "bottom") { + noAuto = true; + } + + if (isHidden) $(m).show(); + var positionTop = $(m).offset().top; + var positionLeft = $(m).offset().left; + if (isHidden) $(m).hide(); + + var xPos = positionTop - $(window).scrollTop(); + + $(m).css({left:"0px"}); + var menuHeight = $(m).outerHeight(); + var menuWidth = $(m).outerWidth(); + $(m).css({left:positionLeft+"px"}); + + var nleft = positionLeft; + if ( positionLeft + menuWidth > $(window).width() ) { + nleft = $(window).width() - menuWidth; + } + + var spaceBottom = true; + if (effect.yposition == "auto" && effect.xposition == "left") { + + if ( xPos + menuHeight + $(el).outerHeight() > $(window).height()) { + spaceBottom = false; + } + } + else { + + if ( xPos + menuHeight > $(window).height()) { + spaceBottom = false; + } + } + + var spaceTop = true; + if (positionTop - menuHeight < 0) { + spaceTop = false; + } + + if (effect.yposition == "bottom") { + positionTop = positionTop + $(el).outerHeight(); + } + + if ( (effect.orientation == "auto" && spaceBottom == false && spaceTop == true) || effect.orientation == "top") { + // top orientation + var ntop = parseInt(positionTop,10) - parseInt(menuHeight,10); + $(m).addClass("topOriented"); + + } else { + // bottom orientation + $(m).addClass("bottomOriented"); + if (effect.yposition == "auto" && effect.xposition == "left") { + positionTop = positionTop + $(el).outerHeight(); + } + var ntop = parseInt(positionTop,10); + } + + $(m).css({"top":ntop+"px", "left":nleft+"px"}); + } + + /* show menu depends to effect.show */ + function showMenu() { + + if (!effect || effect.show == "default") { + $(m).show(); + return false; + } + + var speed = parseInt(effect.speed); + speed = isNaN(speed) ? 500 : speed; + + switch (effect.show) + { + case "fadeIn": + $(m).fadeIn(speed); + break; + + case "slideDown": + $(m).slideDown(speed); + break; + + default: + $(m).show(); + break; + } + } + + /* put item to menu */ + function putItem(n) { + + var item = document.createElement('div'); + $(item).hover(function(){ + $(this).addClass("jj_menu_item_hover") + }, + function(){ + $(this).removeClass("jj_menu_item_hover") + }); + + $(item).click( function(event) { + event.stopPropagation(); + doAction(n.action); + }); + + var span = document.createElement('span'); + $(item).append(span); + + + switch (n.type) + { + case "sub": + item.className = "jj_menu_item jj_menu_item_more"; + $(item).click(function() { + if ($("#jjmenu_"+id+"_sub").length > 0) { + $("div[id^=jjmenu_"+id+"_sub]").remove(); + } + else { + var sub = new menu(id+"_sub", n.src, myReplaces, this, effect); + } + }); + break; + + default: + $(item).hover(function() { $("div[id^=jjmenu_"+id+"_sub]").remove(); }); + item.className = "jj_menu_item"; + break; + } + + + if (n.customClass && n.customClass.length>0) { + jQuery(span).addClass(n.customClass); + } + + $(span).html(uReplace(n.title)); + $(ms).append(item); + } + + /* do action on menu item */ + function doAction(act) { + + $("#jjmenu_main").hide(); + + if (act) { + + switch (act.type) { + + case "gourl": + if (act.target) { + var newWindow = window.open(uReplace(act.url), act.target); + newWindow.focus(); + return false; + } + else { + document.location.href=uReplace(act.url); + } + break; + + case "ajax": + $.getJSON(uReplace(act.url), function(data) { + + var cb = eval(act.callback); + if (typeof(cb) == "function") { + cb(data); + } + + }); + break; + + case "fn": + var callfn = 'var cb = '+act.callback; + jQuery.globalEval(callfn); + if (typeof(cb) == "function") { + cb(myReplaces); + } + break; + } + } + } + + /* replace string with user parameters */ + function uReplace(str) { + if (myReplaces) { + for (var u in myReplaces) { + str = str.replace("#"+u+"#", eval("myReplaces."+u)); + } + } + return str; + } + + /* get effect opbject */ + function getEffect(id, effect) { + + var defEffect = { + show:"default", + xposition:"right", + yposition:"auto", + orientation:"auto" + }; + + if (!effect) { return defEffect; } + + if (!effect.show) effect.show = "default"; + + var show = effect.show; + + if (!effect.xposition) effect.xposition = "right"; + if (!effect.yposition) effect.yposition = "auto"; + if (!effect.orientation) effect.orientation = "auto"; + + if (id != "main") { + var subeffect = defEffect; + subeffect.show = show; + } + + return ( id == "main" ) ? effect : subeffect; + } + } // !menu + }; + + })(jQuery); diff --git a/airtime_mvc/public/js/contextmenu/jjmenu.js b/airtime_mvc/public/js/contextmenu/jjmenu.js index 915377217..d3f08b9fe 100644 --- a/airtime_mvc/public/js/contextmenu/jjmenu.js +++ b/airtime_mvc/public/js/contextmenu/jjmenu.js @@ -44,7 +44,7 @@ { global.click( function(event) { - if (this == event.currentTarget) { + if (this == event.target) { global.pageX = event.pageX; global.pageY = event.pageY; event.preventDefault(); @@ -84,16 +84,6 @@ dynamicItems = true; $.getJSON(uReplace(param[i].get), function(data) { - /* jjmenu doesn't provide ability to add callback function - in case of error. So the error handling has to be included in - the library itself */ - if(data.show_error == true){ - alert("The show instance doesn't exist anymore!"); - window.location.reload(); - }else if(data.playlist_error == true){ - alert("The playlist doesn't exist anymore!"); - window.location.reload(); - } for (var ii in data) { putItem(data[ii]); } @@ -295,8 +285,6 @@ /* do action on menu item */ function doAction(act) { - $("#jjmenu_main").hide(); - if (act) { switch (act.type) { @@ -314,7 +302,7 @@ case "ajax": $.getJSON(uReplace(act.url), function(data) { - + var cb = eval(act.callback); if (typeof(cb) == "function") { cb(data); @@ -374,4 +362,4 @@ } // !menu }; - })(jQuery); + })(jQuery); \ No newline at end of file