diff --git a/airtime_mvc/application/common/UsabilityHints.php b/airtime_mvc/application/common/UsabilityHints.php
index 934d89c2c..0b9ed51b0 100644
--- a/airtime_mvc/application/common/UsabilityHints.php
+++ b/airtime_mvc/application/common/UsabilityHints.php
@@ -55,7 +55,7 @@ class Application_Common_UsabilityHints
return _("Upload some tracks below to add them to your library!");
} else {
return sprintf(_("It looks like you haven't uploaded any audio files yet. %sUpload a file now%s."),
- "",
+ "",
"");
}
} else if (!self::isFutureOrCurrentShowScheduled()) {
@@ -63,7 +63,7 @@ class Application_Common_UsabilityHints
return _("Click the 'New Show' button and fill out the required fields.");
} else {
return sprintf(_("It looks like you don't have any shows scheduled. %sCreate a show now%s."),
- "",
+ "",
"");
}
} else if (self::isCurrentShowEmpty()) {
@@ -73,14 +73,14 @@ class Application_Common_UsabilityHints
return _("To start broadcasting, cancel the current linked show by clicking on it and selecting 'Cancel Show'.");
} else {
return sprintf(_("Linked shows need to be filled with tracks before it starts. To start broadcasting cancel the current linked show and schedule an unlinked show.
- %sCreate an unlinked show now%s."), "", "");
+ %sCreate an unlinked show now%s."), "", "");
}
} else {
if ($userIsOnCalendarPage) {
return _("To start broadcasting, click on the current show and select 'Schedule Show'");
} else {
return sprintf(_("It looks like the current show needs more tracks. %sAdd tracks to your show now%s."),
- "",
+ "",
"");
}
}
@@ -89,7 +89,7 @@ class Application_Common_UsabilityHints
return _("Click on the show starting next and select 'Schedule Show'");
} else {
return sprintf(_("It looks like the next show is empty. %sAdd tracks to your show now%s."),
- "",
+ "",
"");
}
} else {
diff --git a/airtime_mvc/application/controllers/PlaylistController.php b/airtime_mvc/application/controllers/PlaylistController.php
index f9b21cddd..7bb425a7e 100644
--- a/airtime_mvc/application/controllers/PlaylistController.php
+++ b/airtime_mvc/application/controllers/PlaylistController.php
@@ -30,6 +30,7 @@ class PlaylistController extends Zend_Controller_Action
->addActionContext('get-block-info', 'json')
->addActionContext('shuffle', 'json')
->addActionContext('empty-content', 'json')
+ ->addActionContext('change-playlist', 'json')
->initContext();
//This controller writes to the session all over the place, so we're going to reopen it for writing here.
@@ -201,6 +202,16 @@ class PlaylistController extends Zend_Controller_Action
$this->createFullResponse($obj);
}
+ public function changePlaylistAction() {
+ $this->view->layout()->disableLayout(); // Don't inject the standard Now Playing header.
+ $this->_helper->viewRenderer->setNoRender(true); // Don't use (phtml) templates
+
+ $id = $this->_getParam('id', null);
+ $type = $this->_getParam('type');
+
+ Application_Model_Library::changePlaylist($id, $type);
+ }
+
public function editAction()
{
$id = $this->_getParam('id', null);
@@ -241,7 +252,7 @@ class PlaylistController extends Zend_Controller_Action
Logging::info("Currently active {$type} {$obj_sess->id}");
if (in_array($obj_sess->id, $ids)) {
Logging::info("Deleting currently active {$type}");
- Application_Model_Library::changePlaylist(null, $type);
+ // Application_Model_Library::changePlaylist(null, $type);
} else {
Logging::info("Not deleting currently active {$type}");
$obj = new $objInfo['className']($obj_sess->id);
diff --git a/airtime_mvc/application/controllers/plugins/Acl_plugin.php b/airtime_mvc/application/controllers/plugins/Acl_plugin.php
index fb87574e0..18f1c69a5 100644
--- a/airtime_mvc/application/controllers/plugins/Acl_plugin.php
+++ b/airtime_mvc/application/controllers/plugins/Acl_plugin.php
@@ -82,7 +82,7 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
* @param string $module
* @return void
**/
- public function setErrorPage($action, $controller = 'error', $module = null)
+ public function setErrorPage($action, $controller = 'error', $module = 'default')
{
$this->_errorPage = array('module' => $module,
'controller' => $controller,
@@ -204,11 +204,8 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
$resourceName,
$request->getActionName())) {
/** Redirect to access denied page */
- $this->getResponse()
- ->setHttpResponseCode(403)
- ->appendBody("You don't have permission to access this resource.")
- ->sendResponse();
- // $this->denyAccess(); /* This results in a 404! */
+ $this->setErrorPage('error403');
+ $this->denyAccess(); /* This results in a 404! */
}
}
}
diff --git a/airtime_mvc/application/services/CalendarService.php b/airtime_mvc/application/services/CalendarService.php
index 853052644..e85814afb 100644
--- a/airtime_mvc/application/services/CalendarService.php
+++ b/airtime_mvc/application/services/CalendarService.php
@@ -142,7 +142,8 @@ class Application_Service_CalendarService
if ($isRepeating) {
if ($populateInstance) {
$menu["edit"] = array(
- "name" => _("Edit This Instance"),
+ // "name" => _("Edit This Instance"),
+ "name" => _("Edit Instance"),
"icon" => "edit",
"url" => $baseUrl . "Schedule/populate-repeating-show-instance-form"
);
@@ -160,7 +161,8 @@ class Application_Service_CalendarService
);
$menu["edit"]["items"]["instance"] = array(
- "name" => _("Edit This Instance"),
+ // "name" => _("Edit This Instance"),
+ "name" => _("Edit Instance"),
"icon" => "edit",
"url" => $baseUrl . "Schedule/populate-repeating-show-instance-form"
);
@@ -188,12 +190,14 @@ class Application_Service_CalendarService
"items" => array());
$menu["del"]["items"]["single"] = array(
- "name"=> _("Delete This Instance"),
+ // "name"=> _("Delete This Instance"),
+ "name"=> _("Delete Instance"),
"icon" => "delete",
"url" => $baseUrl."schedule/delete-show-instance");
$menu["del"]["items"]["following"] = array(
- "name"=> _("Delete This Instance and All Following"),
+ // "name"=> _("Delete This Instance and All Following"),
+ "name"=> _("Delete Instance and All Following"),
"icon" => "delete",
"url" => $baseUrl."schedule/delete-show");
} elseif ($populateInstance) {
diff --git a/airtime_mvc/public/css/dashboard.css b/airtime_mvc/public/css/dashboard.css
index d92d1041b..c30d2e848 100644
--- a/airtime_mvc/public/css/dashboard.css
+++ b/airtime_mvc/public/css/dashboard.css
@@ -150,6 +150,9 @@ div.btn > span {
#library_empty_image {
opacity: .3;
+ width: 16px;
+ height: 20px;
+
top: -20px;
margin-top: -2px;
padding-right: 2px; /* For the webstream icon */
@@ -456,8 +459,10 @@ li.ui-state-default {
max-height: 60%;
overflow-x: hidden;
width: 100%;
- flex: 1 0 100%;
+ flex: 1 0 auto;
padding: 10px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
}
@@ -500,6 +505,8 @@ li.ui-state-default {
padding: 5px;
border: 1px solid #444;
border-radius: 3px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
background-color: #111;
display: flex;
@@ -559,6 +566,8 @@ li.ui-state-default {
}
.side_playlist .zend_form input {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
height: 26px;
}
diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css
index c58102ad5..f2a21787d 100644
--- a/airtime_mvc/public/css/styles.css
+++ b/airtime_mvc/public/css/styles.css
@@ -1357,6 +1357,8 @@ input[type="checkbox"] {
}
#schedule_calendar {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
@@ -1819,6 +1821,8 @@ button, input {
}
.user-management .dataTables_filter input {
width: 100%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
margin-bottom:8px;
}
@@ -1945,7 +1949,9 @@ div.success{
float: right;
height: 30px;
line-height: 24px;
- box-sizing: border-box;;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
div.errors, span.errors{
@@ -1957,7 +1963,9 @@ div.errors, span.errors{
border:1px solid #c83f3f;
height: 30px;
line-height: 24px;
- box-sizing: border-box;;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
}
span.errors.sp-errors{
@@ -2625,6 +2633,8 @@ label span {
fieldset > legend {
width: 100%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
background: #333;
@@ -3462,9 +3472,15 @@ dd .stream-status {
min-width: 200px !important;
}
+.calendar-context-menu .context-menu-list {
+ min-width: 260px !important;
+}
+
/* Add Media Page */
#upload_form, #recent_uploads_wrapper {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
}
@@ -3593,6 +3609,8 @@ button.btn-icon-text > i.icon-white {
.dashboard_sub_nav {
padding: 0px 0px 0px 10px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
}
@@ -3722,6 +3740,8 @@ button.btn-icon-text > i.icon-white {
#listenerstat_content {
width: 100%;
display: block;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
box-sizing: border-box;
}
@@ -3734,6 +3754,12 @@ button.btn-icon-text > i.icon-white {
font-size: 12px;
}
+#flot_placeholder.processing {
+ width: 100%;
+ height: 100%;
+ background: url("img/loading.gif") no-repeat 50% 50% rgba(0, 0, 0, .25);
+}
+
.dashboard-btn {
width: 50%;
}
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 6cdf9d394..3459c862d 100644
--- a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js
+++ b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js
@@ -77,6 +77,7 @@ var AIRTIME = (function(AIRTIME) {
cb.append("");
}
+ var libEmpty = $('#library_empty');
if (emptyRow.length > 0) {
emptyRow.hide();
var mediaType = parseInt($('.media_type_selector.selected').attr('data-selection-id')),
@@ -92,13 +93,13 @@ var AIRTIME = (function(AIRTIME) {
$('#library_empty_text').html(
$.i18n._("You haven't added any " + opts.media + ".")
+ "
" + $.i18n._(opts.subtext)
- + "
" + $.i18n._("Learn about " + opts.media) + ""
+ + "
" + $.i18n._("Learn about " + opts.media) + ""
);
- }) ;
+ });
- $('#library_empty').show();
+ libEmpty.show();
} else {
- $('#library_empty').hide();
+ libEmpty.hide();
}
if ($("#show_builder_table").is(":visible")) {
diff --git a/airtime_mvc/public/js/airtime/library/spl.js b/airtime_mvc/public/js/airtime/library/spl.js
index ca9ca135a..22cacd1fb 100644
--- a/airtime_mvc/public/js/airtime/library/spl.js
+++ b/airtime_mvc/public/js/airtime/library/spl.js
@@ -421,17 +421,19 @@ var AIRTIME = (function(AIRTIME){
$('.zend_form + .spl-no-margin > div:has(*:visible):last').css('margin-left', 0);
}
- function getId() {
- return parseInt($pl.find(".obj_id").val(), 10);
+ function getId(pl) {
+ pl = (pl === undefined) ? $pl : pl;
+ return parseInt(pl.find(".obj_id").val(), 10);
}
- mod.getModified = function() {
- return parseInt($pl.find(".obj_lastMod").val(), 10);
- }
+ mod.getModified = function(pl) {
+ pl = (pl === undefined) ? $pl : pl;
+ return parseInt(pl.find(".obj_lastMod").val(), 10);
+ };
mod.setModified = function(modified) {
$pl.find(".obj_lastMod").val(modified);
- }
+ };
function setTitleLabel(title) {
$pl.find(".title_obj_name").text(title);
@@ -569,6 +571,10 @@ var AIRTIME = (function(AIRTIME){
if (pane.get(0) == curr.get(0)) { // Closing the current tab, otherwise we don't need to switch tabs
AIRTIME.showbuilder.switchTab(toPane, toTab);
}
+
+ // If we close a tab that was causing tabs to wrap to the next row, we need to resize to change the
+ // margin for the tab nav
+ AIRTIME.playlist.onResize();
}
mod.closeTab = function(id) {
@@ -1208,8 +1214,8 @@ var AIRTIME = (function(AIRTIME){
var url, id, lastMod, type, pl = (tabId === undefined) ? $pl : $('#pl-tab-content-' + tabId);
stopAudioPreview();
- id = (plid === undefined) ? getId() : plid;
- lastMod = mod.getModified();
+ id = (plid === undefined) ? getId(pl) : plid;
+ lastMod = mod.getModified(pl);
type = pl.find('.obj_type').val();
url = baseUrl+'playlist/delete';
@@ -1558,6 +1564,7 @@ var AIRTIME = (function(AIRTIME){
mod.setAsActive = function() {
$pl = $(".active-tab");
+ $.post(baseUrl + "playlist/change-playlist", {"id": getId(), "type": $pl.find('.obj_type').val()});
};
mod.init = function() {
diff --git a/airtime_mvc/public/js/airtime/listenerstat/listenerstat.js b/airtime_mvc/public/js/airtime/listenerstat/listenerstat.js
index 8507c876e..0c239455f 100644
--- a/airtime_mvc/public/js/airtime/listenerstat/listenerstat.js
+++ b/airtime_mvc/public/js/airtime/listenerstat/listenerstat.js
@@ -10,7 +10,7 @@ $(document).ready(function() {
width = width * .91;
$("#listenerstat_content").find("#flot_placeholder").width(width);
$("#listenerstat_content").find("#legend").width(width);
-
+
getDataAndPlot();
listenerstat_content.find("#his_submit").click(function(){
@@ -21,7 +21,17 @@ $(document).ready(function() {
});
});
-function getDataAndPlot(startTimestamp, endTimestamp){
+/**
+ * Toggle a spinner overlay so the user knows the page is processing
+ */
+function toggleOverlay() {
+ $('#flot_placeholder').toggleClass('processing');
+}
+
+function getDataAndPlot(startTimestamp, endTimestamp) {
+ // Turn on the processing overlay
+ toggleOverlay();
+
// get data
$.get(baseUrl+'Listenerstat/get-data', {start: startTimestamp, end: endTimestamp}, function(data){
out = new Object();
@@ -37,6 +47,8 @@ function getDataAndPlot(startTimestamp, endTimestamp){
out[mpName] = plotData;
});
plot(out);
+ // Turn off the processing overlay
+ toggleOverlay();
})
}
diff --git a/airtime_mvc/public/js/airtime/user/user.js b/airtime_mvc/public/js/airtime/user/user.js
index e277d4266..921369546 100644
--- a/airtime_mvc/public/js/airtime/user/user.js
+++ b/airtime_mvc/public/js/airtime/user/user.js
@@ -43,10 +43,16 @@ function rowClickCallback(row_id){
}});
}
-function removeUserCallback(row_id, nRow){
- $.ajax({ url: baseUrl+'User/remove-user/id/'+ row_id +'/format/json', dataType:"text", success:function(data){
- var o = $('#users_datatable').dataTable().fnDeleteRow(nRow);
- }});
+function removeUserCallback(row_id, nRow) {
+ if (confirm($.i18n._("Are you sure you want to delete this user?"))) {
+ $.ajax({
+ url: baseUrl + 'User/remove-user/id/' + row_id + '/format/json',
+ dataType: "text",
+ success: function (data) {
+ var o = $('#users_datatable').dataTable().fnDeleteRow(nRow);
+ }
+ });
+ }
}
function rowCallback( nRow, aData, iDisplayIndex ){