Merge branch 'devel' of dev.sourcefabric.org:airtime into devel
This commit is contained in:
commit
6e77f2637a
21
CREDITS
21
CREDITS
|
@ -1,6 +1,27 @@
|
|||
=======
|
||||
CREDITS
|
||||
=======
|
||||
|
||||
Version 2.2.1
|
||||
-------------
|
||||
Martin Konecny (martin.konecny@sourcefabric.org)
|
||||
Role: Developer Team Lead
|
||||
|
||||
James Moon (james.moon@sourcefabric.org)
|
||||
Role: Software Developer
|
||||
|
||||
Denise Rigato (denise.rigato@sourcefabric.org)
|
||||
Role: Software Developer
|
||||
|
||||
Cliff Wang (cliff.wang@sourcefabric.org)
|
||||
Role: QA
|
||||
|
||||
Mikayel Karapetian (michael.karapetian@sourcefabric.org)
|
||||
Role: QA
|
||||
|
||||
Daniel James (daniel.james@sourcefabric.org)
|
||||
Role: Documentor & QA
|
||||
|
||||
Version 2.2.0
|
||||
-------------
|
||||
Martin Konecny (martin.konecny@sourcefabric.org)
|
||||
|
|
2
README
2
README
|
@ -8,7 +8,7 @@ Home page: http://airtime.sourcefabric.org/
|
|||
|
||||
Major features:
|
||||
* Web-based remote station management. Authorized personnel can add
|
||||
program material, create playlists, and schedule programming all via
|
||||
program material, create playlists and schedule programming all via
|
||||
a web interface.
|
||||
* Automation. Airtime has a scheduler function that enables users to
|
||||
set shows with playlists for playback at a date and time of their choosing.
|
||||
|
|
|
@ -88,6 +88,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
$view->headLink()->appendStylesheet($baseUrl.'/css/styles.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'/css/masterpanel.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'/css/bootstrap.css?'.$CC_CONFIG['airtime_version']);
|
||||
$view->headLink()->appendStylesheet($baseUrl.'/css/tipsy/jquery.tipsy.css?'.$CC_CONFIG['airtime_version']);
|
||||
}
|
||||
|
||||
protected function _initHeadScript()
|
||||
|
@ -116,7 +117,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
$view->headScript()->appendFile($baseUrl.'/js/airtime/dashboard/helperfunctions.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'/js/airtime/dashboard/dashboard.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'/js/airtime/dashboard/versiontooltip.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$view->headScript()->appendFile($baseUrl.'/js/tipsy/jquery.tipsy.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
||||
$view->headScript()->appendFile($baseUrl.'/js/airtime/common/common.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
$view->headScript()->appendFile($baseUrl.'/js/airtime/common/audioplaytest.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
|
|
|
@ -33,6 +33,7 @@ $ccAcl->add(new Zend_Acl_Resource('library'))
|
|||
$ccAcl->allow('G', 'index')
|
||||
->allow('G', 'login')
|
||||
->allow('G', 'error')
|
||||
->allow('G', 'user', 'edit-user')
|
||||
->allow('G', 'showbuilder')
|
||||
->allow('G', 'api')
|
||||
->allow('G', 'schedule')
|
||||
|
|
|
@ -307,6 +307,26 @@ class LocaleController extends Zend_Controller_Action
|
|||
"DJ" => _("DJ"),
|
||||
"Program Manager" => _("Program Manager"),
|
||||
"Guest" => _("Guest"),
|
||||
"Guests can do the following:" => _("Guests can do the following:"),
|
||||
"View schedule" => _("View schedule"),
|
||||
"View show content" => _("View show content"),
|
||||
"DJs can do the following:" => _("DJs can do the following:"),
|
||||
"Manage assigned show content" => _("Manage assigned show content"),
|
||||
"Import media files" => _("Import media files"),
|
||||
"Create playlists, smart blocks, and webstreams" => _("Create playlists, smart blocks, and webstreams"),
|
||||
"Manage their own library content" => _("Manage their own library content"),
|
||||
"Progam Managers can do the following:" => _("Progam Managers can do the following:"),
|
||||
"View and manage show content" => _("View and manage show content"),
|
||||
"Schedule shows" => _("Schedule shows"),
|
||||
"Manage all library content" => _("Manage all library content"),
|
||||
"Admins can do the following:" => _("Admins can do the following:"),
|
||||
"Manage preferences" => _("Manage preferences"),
|
||||
"Manage users" => _("Manage users"),
|
||||
"Manage watched folders" => _("Manage watched folders"),
|
||||
"Send support feedback" => _("Send support feedback"),
|
||||
"View system status" => _("View system status"),
|
||||
"Access playout history" => _("Access playout history"),
|
||||
"View listener stats" => _("View listener stats"),
|
||||
//dataTables/ColVis.js
|
||||
"Show / hide columns" => _("Show / hide columns"),
|
||||
//datatables.columnFilter.js
|
||||
|
|
|
@ -255,6 +255,7 @@ class PreferenceController extends Zend_Controller_Action
|
|||
Application_Model_Preference::SetDefaultTransitionFade($values["transition_fade"]);
|
||||
Application_Model_Preference::SetAutoTransition($values["auto_transition"]);
|
||||
Application_Model_Preference::SetAutoSwitch($values["auto_switch"]);
|
||||
Application_Model_Preference::setReplayGainModifier($values["replayGainModifier"]);
|
||||
|
||||
if (!Application_Model_Preference::GetMasterDjConnectionUrlOverride()) {
|
||||
$master_connection_url = "http://".$_SERVER['SERVER_NAME'].":".$values["master_harbor_input_port"]."/".$values["master_harbor_input_mount_point"];
|
||||
|
|
|
@ -10,6 +10,7 @@ class UserController extends Zend_Controller_Action
|
|||
->addActionContext('get-user-data-table-info', 'json')
|
||||
->addActionContext('get-user-data', 'json')
|
||||
->addActionContext('remove-user', 'json')
|
||||
->addActionContext('edit-user', 'json')
|
||||
->initContext();
|
||||
}
|
||||
|
||||
|
@ -114,6 +115,49 @@ class UserController extends Zend_Controller_Action
|
|||
$id = $this->_getParam('id');
|
||||
$this->view->entries = Application_Model_User::GetUserData($id);
|
||||
}
|
||||
|
||||
public function editUserAction()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$form = new Application_Form_EditUser();
|
||||
if ($request->isPost()) {
|
||||
$params = $request->getPost();
|
||||
$postData = explode('&', $params['data']);
|
||||
foreach($postData as $k=>$v) {
|
||||
$v = explode('=', $v);
|
||||
$formData[$v[0]] = urldecode($v[1]);
|
||||
}
|
||||
|
||||
if (isset($CC_CONFIG['demo']) && $CC_CONFIG['demo'] == 1
|
||||
&& $formData['cu_login'] == 'admin') {
|
||||
$this->view->form = $form;
|
||||
$this->view->successMessage = "<div class='errors'>"._("Specific action is not allowed in demo version!")."</div>";
|
||||
die(json_encode(array("html"=>$this->view->render('user/edit-user.phtml'))));
|
||||
} else if ($form->isValid($formData) &&
|
||||
$form->validateLogin($formData['cu_login'], $formData['cu_user_id'])) {
|
||||
$user = new Application_Model_User($formData['cu_user_id']);
|
||||
$user->setFirstName($formData['cu_first_name']);
|
||||
$user->setLastName($formData['cu_last_name']);
|
||||
$user->setLogin($formData['cu_login']);
|
||||
// We don't allow 6 x's as a password.
|
||||
// The reason is because we use that as a password placeholder
|
||||
// on the client side.
|
||||
if ($formData['cu_password'] != "xxxxxx") {
|
||||
$user->setPassword($formData['cu_password']);
|
||||
}
|
||||
$user->setEmail($formData['cu_email']);
|
||||
$user->setCellPhone($formData['cu_cell_phone']);
|
||||
$user->setSkype($formData['cu_skype']);
|
||||
$user->setJabber($formData['cu_jabber']);
|
||||
$user->save();
|
||||
$this->view->successMessage = "<div class='success'>"._("User updated successfully!")."</div>";
|
||||
}
|
||||
$this->view->form = $form;
|
||||
die(json_encode(array("html"=>$this->view->render('user/edit-user.phtml'))));
|
||||
}
|
||||
$this->view->form = $form;
|
||||
$this->view->html = $this->view->render('user/edit-user.phtml');
|
||||
}
|
||||
|
||||
public function removeUserAction()
|
||||
{
|
||||
|
|
|
@ -40,14 +40,12 @@ class Application_Form_AddUser extends Zend_Form
|
|||
$firstName->setLabel(_('Firstname:'));
|
||||
$firstName->setAttrib('class', 'input_text');
|
||||
$firstName->addFilter('StringTrim');
|
||||
$firstName->addValidator($notEmptyValidator);
|
||||
$this->addElement($firstName);
|
||||
|
||||
$lastName = new Zend_Form_Element_Text('last_name');
|
||||
$lastName->setLabel(_('Lastname:'));
|
||||
$lastName->setAttrib('class', 'input_text');
|
||||
$lastName->addFilter('StringTrim');
|
||||
$lastName->addValidator($notEmptyValidator);
|
||||
$this->addElement($lastName);
|
||||
|
||||
$email = new Zend_Form_Element_Text('email');
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
class Application_Form_EditUser extends Zend_Form
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
/*
|
||||
$this->addElementPrefixPath('Application_Validate',
|
||||
'../application/validate',
|
||||
'validate');
|
||||
* */
|
||||
|
||||
$currentUser = Application_Model_User::getCurrentUser();
|
||||
$userData = Application_Model_User::GetUserData($currentUser->getId());
|
||||
$notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator();
|
||||
$emailValidator = Application_Form_Helper_ValidationTypes::overrideEmailAddressValidator();
|
||||
|
||||
$this->setDecorators(array(
|
||||
array('ViewScript', array('viewScript' => 'form/edit-user.phtml'))));
|
||||
$this->setAttrib('id', 'current-user-form');
|
||||
|
||||
$hidden = new Zend_Form_Element_Hidden('cu_user_id');
|
||||
$hidden->setDecorators(array('ViewHelper'));
|
||||
$hidden->setValue($userData["id"]);
|
||||
$this->addElement($hidden);
|
||||
|
||||
$login = new Zend_Form_Element_Text('cu_login');
|
||||
$login->setLabel(_('Username:'));
|
||||
$login->setValue($userData["login"]);
|
||||
$login->setAttrib('class', 'input_text');
|
||||
$login->setRequired(true);
|
||||
$login->addValidator($notEmptyValidator);
|
||||
$login->addFilter('StringTrim');
|
||||
$login->setDecorators(array('viewHelper'));
|
||||
$this->addElement($login);
|
||||
|
||||
$password = new Zend_Form_Element_Password('cu_password');
|
||||
$password->setLabel(_('Password:'));
|
||||
$password->setAttrib('class', 'input_text');
|
||||
$password->setRequired(true);
|
||||
$password->addFilter('StringTrim');
|
||||
$password->addValidator($notEmptyValidator);
|
||||
$password->setDecorators(array('viewHelper'));
|
||||
$this->addElement($password);
|
||||
|
||||
$firstName = new Zend_Form_Element_Text('cu_first_name');
|
||||
$firstName->setLabel(_('Firstname:'));
|
||||
$firstName->setValue($userData["first_name"]);
|
||||
$firstName->setAttrib('class', 'input_text');
|
||||
$firstName->addFilter('StringTrim');
|
||||
$firstName->setDecorators(array('viewHelper'));
|
||||
$this->addElement($firstName);
|
||||
|
||||
$lastName = new Zend_Form_Element_Text('cu_last_name');
|
||||
$lastName->setLabel(_('Lastname:'));
|
||||
$lastName->setValue($userData["last_name"]);
|
||||
$lastName->setAttrib('class', 'input_text');
|
||||
$lastName->addFilter('StringTrim');
|
||||
$lastName->setDecorators(array('viewHelper'));
|
||||
$this->addElement($lastName);
|
||||
|
||||
$email = new Zend_Form_Element_Text('cu_email');
|
||||
$email->setLabel(_('Email:'));
|
||||
$email->setValue($userData["email"]);
|
||||
$email->setAttrib('class', 'input_text');
|
||||
$email->addFilter('StringTrim');
|
||||
$email->setRequired(true);
|
||||
$email->addValidator($notEmptyValidator);
|
||||
$email->addValidator($emailValidator);
|
||||
$email->setDecorators(array('viewHelper'));
|
||||
$this->addElement($email);
|
||||
|
||||
$cellPhone = new Zend_Form_Element_Text('cu_cell_phone');
|
||||
$cellPhone->setLabel(_('Mobile Phone:'));
|
||||
$cellPhone->setValue($userData["cell_phone"]);
|
||||
$cellPhone->setAttrib('class', 'input_text');
|
||||
$cellPhone->addFilter('StringTrim');
|
||||
$cellPhone->setDecorators(array('viewHelper'));
|
||||
$this->addElement($cellPhone);
|
||||
|
||||
$skype = new Zend_Form_Element_Text('cu_skype');
|
||||
$skype->setLabel(_('Skype:'));
|
||||
$skype->setValue($userData["skype_contact"]);
|
||||
$skype->setAttrib('class', 'input_text');
|
||||
$skype->addFilter('StringTrim');
|
||||
$skype->setDecorators(array('viewHelper'));
|
||||
$this->addElement($skype);
|
||||
|
||||
$jabber = new Zend_Form_Element_Text('cu_jabber');
|
||||
$jabber->setLabel(_('Jabber:'));
|
||||
$jabber->setValue($userData["jabber_contact"]);
|
||||
$jabber->setAttrib('class', 'input_text');
|
||||
$jabber->addFilter('StringTrim');
|
||||
$jabber->addValidator($emailValidator);
|
||||
$jabber->setDecorators(array('viewHelper'));
|
||||
$this->addElement($jabber);
|
||||
|
||||
/*
|
||||
$saveBtn = new Zend_Form_Element_Button('cu_save_user');
|
||||
$saveBtn->setAttrib('class', 'btn btn-small right-floated');
|
||||
$saveBtn->setIgnore(true);
|
||||
$saveBtn->setLabel(_('Save'));
|
||||
$saveBtn->setDecorators(array('viewHelper'));
|
||||
$this->addElement($saveBtn);
|
||||
*/
|
||||
}
|
||||
|
||||
public function validateLogin($p_login, $p_userId) {
|
||||
$count = CcSubjsQuery::create()
|
||||
->filterByDbLogin($p_login)
|
||||
->filterByDbId($p_userId, Criteria::NOT_EQUAL)
|
||||
->count();
|
||||
|
||||
if ($count != 0) {
|
||||
$this->getElement('cu_login')->setErrors(array(_("Login name is not unique.")));
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -58,6 +58,13 @@ class Application_Form_StreamSetting extends Zend_Form
|
|||
$stream_format->setValue(Application_Model_Preference::GetStreamLabelFormat());
|
||||
$stream_format->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($stream_format);
|
||||
|
||||
$replay_gain = new Zend_Form_Element_Hidden("replayGainModifier");
|
||||
$replay_gain->setLabel(_("Replay Gain Modifier"))
|
||||
->setValue(Application_Model_Preference::getReplayGainModifier())
|
||||
->setAttribs(array('style' => "border: 0; color: #f6931f; font-weight: bold;"))
|
||||
->setDecorators(array('ViewHelper'));
|
||||
$this->addElement($replay_gain);
|
||||
}
|
||||
|
||||
public function isValid($data)
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
$this->navigation()->menu()->setPartial($partial); ?>
|
||||
<div class="personal-block solo">
|
||||
<ul>
|
||||
<li><span class="name"><?php echo $this->loggedInAs()?></span> | <a href=<?php echo $baseUrl . "/Login/logout"?>><?php echo _("Logout")?></a></li>
|
||||
<li>
|
||||
<a id="current-user" href="#"><span class="name"><?php echo $this->loggedInAs()?></span></a> | <a href=<?php echo $baseUrl . "/Login/logout"?>><?php echo _("Logout")?></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1183,4 +1183,19 @@ class Application_Model_Preference
|
|||
$data = self::getValue("nowplaying_screen", true);
|
||||
return ($data != "") ? unserialize($data) : null;
|
||||
}
|
||||
|
||||
public static function getReplayGainModifier(){
|
||||
$rg_modifier = self::getValue("replay_gain_modifier");
|
||||
|
||||
if ($rg_modifier === "") {
|
||||
return "0";
|
||||
}
|
||||
|
||||
return $rg_modifier;
|
||||
}
|
||||
|
||||
public static function setReplayGainModifier($rg_modifier)
|
||||
{
|
||||
self::setValue("replay_gain_modifier", $rg_modifier, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -679,6 +679,8 @@ SQL;
|
|||
|
||||
$same_hour = $start_hour == $end_hour;
|
||||
$independent_event = !$same_hour;
|
||||
$replay_gain = is_null($item["replay_gain"]) ? "0": $item["replay_gain"];
|
||||
$replay_gain += Application_Model_Preference::getReplayGainModifier();
|
||||
|
||||
$schedule_item = array(
|
||||
'id' => $media_id,
|
||||
|
@ -692,7 +694,7 @@ SQL;
|
|||
'start' => $start,
|
||||
'end' => $end,
|
||||
'show_name' => $item["show_name"],
|
||||
'replay_gain' => is_null($item["replay_gain"]) ? "0": $item["replay_gain"],
|
||||
'replay_gain' => $replay_gain,
|
||||
'independent_event' => $independent_event,
|
||||
);
|
||||
self::appendScheduleItem($data, $start, $schedule_item);
|
||||
|
|
|
@ -309,7 +309,7 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable
|
|||
$media_url = self::getXspfUrl($url);
|
||||
} elseif (preg_match("/pls\+xml/", $mime) || preg_match("/x-scpls/", $mime)) {
|
||||
$media_url = self::getPlsUrl($url);
|
||||
} elseif (preg_match("/(mpeg|ogg)/", $mime)) {
|
||||
} elseif (preg_match("/(mpeg|ogg|audio\/aacp)/", $mime)) {
|
||||
if ($content_length_found) {
|
||||
throw new Exception(_("Invalid webstream - This appears to be a file download."));
|
||||
}
|
||||
|
@ -322,10 +322,49 @@ class Application_Model_Webstream implements Application_Model_LibraryEditable
|
|||
|
||||
}
|
||||
|
||||
/* PHP get_headers has an annoying property where if the passed in URL is
|
||||
* a redirect, then it goes to the new URL, and returns headers from both
|
||||
* requests. We only want the headers from the final request. Here's an
|
||||
* example:
|
||||
*
|
||||
* 0 => "HTTP/1.1 302 Moved Temporarily",
|
||||
* 1 => "X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.1 Java/Sun Microsystems Inc./1.6)",
|
||||
* 2 => "Server: GlassFish Server Open Source Edition 3.1.1",
|
||||
* 3 => "Location: http://3043.live.streamtheworld.com:80/SAM04AAC89_SC",
|
||||
* 4 => "Content-Type: text/html;charset=ISO-8859-1",
|
||||
* 5 => "Content-Language: en-US",
|
||||
* 6 => "Content-Length: 202",
|
||||
* 7 => "Date: Thu, 27 Dec 2012 21:52:59 GMT",
|
||||
* 8 => "Connection: close",
|
||||
* 9 => "HTTP/1.0 200 OK",
|
||||
* 10 => "Expires: Thu, 01 Dec 2003 16:00:00 GMT",
|
||||
* 11 => "Cache-Control: no-cache, must-revalidate",
|
||||
* 12 => "Pragma: no-cache",
|
||||
* 13 => "Content-Type: audio/aacp",
|
||||
* 14 => "icy-br: 68",
|
||||
* 15 => "Server: MediaGateway 3.2.1-04",
|
||||
* */
|
||||
private static function cleanHeaders($headers) {
|
||||
//find the position of HTTP/1 200 OK
|
||||
//
|
||||
$position = 0;
|
||||
foreach ($headers as $i => $v) {
|
||||
if (preg_match("/^HTTP.*200 OK$/i", $v)) {
|
||||
$position = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array_slice($headers, $position);
|
||||
}
|
||||
|
||||
private static function discoverStreamMime($url)
|
||||
{
|
||||
//TODO: What if invalid URL?
|
||||
$headers = get_headers($url);
|
||||
|
||||
$headers = self::cleanHeaders($headers);
|
||||
|
||||
$mime = null;
|
||||
$content_length_found = false;
|
||||
foreach ($headers as $h) {
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
<div id="current-user-container">
|
||||
<form id="current-user-form" class="edit-user-global" enctype="application/x-www-form-urlencoded">
|
||||
<dl class="zend_form">
|
||||
<?php echo $this->element->getElement('cu_user_id') ?>
|
||||
<dt id="cu-username-label">
|
||||
<label><?php echo $this->element->getElement('cu_login')->getLabel() ?>
|
||||
</label>
|
||||
</dt>
|
||||
<dd id="cu-username-element">
|
||||
<?php echo $this->element->getElement('cu_login') ?>
|
||||
<?php if($this->element->getElement('cu_login')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->element->getElement('cu_login')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt id="cu-password-label">
|
||||
<label><?php echo $this->element->getElement('cu_password')->getLabel() ?>
|
||||
</label>
|
||||
</dt>
|
||||
<dd id="cu-password-element">
|
||||
<?php echo $this->element->getElement('cu_password') ?>
|
||||
<?php if($this->element->getElement('cu_password')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->element->getElement('cu_password')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt id="cu-firstname-label">
|
||||
<label><?php echo $this->element->getElement('cu_first_name')->getLabel() ?>
|
||||
</label>
|
||||
</dt>
|
||||
<dd id="cu-firstname-element">
|
||||
<?php echo $this->element->getElement('cu_first_name') ?>
|
||||
<?php if($this->element->getElement('cu_first_name')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->element->getElement('cu_first_name')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt id="cu-lastname-label">
|
||||
<label><?php echo $this->element->getElement('cu_last_name')->getLabel() ?>
|
||||
</label>
|
||||
</dt>
|
||||
<dd id="cu-lastname-element">
|
||||
<?php echo $this->element->getElement('cu_last_name') ?>
|
||||
<?php if($this->element->getElement('cu_last_name')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->element->getElement('cu_last_name')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt id="cu-email-label">
|
||||
<label><?php echo $this->element->getElement('cu_email')->getLabel() ?>
|
||||
</label>
|
||||
</dt>
|
||||
<dd id="cu-email-element">
|
||||
<?php echo $this->element->getElement('cu_email') ?>
|
||||
<?php if($this->element->getElement('cu_email')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->element->getElement('cu_email')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt id="cu-cell_phone-label">
|
||||
<label><?php echo $this->element->getElement('cu_cell_phone')->getLabel() ?>
|
||||
</label>
|
||||
</dt>
|
||||
<dd id="cu-cell_phone-element">
|
||||
<?php echo $this->element->getElement('cu_cell_phone') ?>
|
||||
<?php if($this->element->getElement('cu_cell_phone')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->element->getElement('cu_cell_phone')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt id="cu-skype-label">
|
||||
<label><?php echo $this->element->getElement('cu_skype')->getLabel() ?>
|
||||
</label>
|
||||
</dt>
|
||||
<dd id="cu-skype-element">
|
||||
<?php echo $this->element->getElement('cu_skype') ?>
|
||||
<?php if($this->element->getElement('cu_skype')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->element->getElement('cu_skype')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt id="cu-jabber-label">
|
||||
<label><?php echo $this->element->getElement('cu_jabber')->getLabel() ?>
|
||||
</label>
|
||||
</dt>
|
||||
<dd id="cu-jabber-element">
|
||||
<?php echo $this->element->getElement('cu_jabber') ?>
|
||||
<?php if($this->element->getElement('cu_jabber')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->element->getElement('cu_jabber')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<button id="cu_save_user" type="button" class="btn btn-small right-floated">Save</button>
|
||||
</dl>
|
||||
</form>
|
||||
</div>
|
|
@ -108,6 +108,5 @@
|
|||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
|
|
@ -63,6 +63,24 @@
|
|||
</ul>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<dt id="replayGainModifier-label" class="block-display">
|
||||
<label><?php echo $this->form->getElement('replayGainModifier')->getLabel() ?>:
|
||||
</label>
|
||||
<span id="rg_modifier_value" style="border: 0; color: #f6931f; font-weight: bold;">
|
||||
<?php echo $this->form->getElement('replayGainModifier')->getValue() ?>
|
||||
</span>
|
||||
</dt>
|
||||
<dd id="replayGainModifier-element" class="block-display">
|
||||
<?php echo $this->form->getElement('replayGainModifier') ?>
|
||||
<?php if($this->form->getElement('replayGainModifier')->hasErrors()) : ?>
|
||||
<ul class='errors'>
|
||||
<?php foreach($this->form->getElement('replayGainModifier')->getMessages() as $error): ?>
|
||||
<li><?php echo $error; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
<div id="slider-range-max"></div>
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
<?php echo $this->form->getSubform('live_stream_subform'); ?>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
<?php echo $this->successMessage ?>
|
||||
<?php echo $this->form?>
|
|
@ -314,9 +314,11 @@ INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_channels', 'ste
|
|||
INSERT INTO cc_pref("keystr", "valstr") VALUES('locale', 'en_CA');
|
||||
|
||||
INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('en_CA', 'English');
|
||||
INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('en_US', 'English - US');
|
||||
INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('fr_FR', 'French');
|
||||
INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('de_DE', 'German');
|
||||
INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('ko_KR', 'Korean');
|
||||
INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('ru_RU', 'Russian');
|
||||
INSERT INTO cc_locale (locale_code, locale_lang) VALUES ('es_ES', 'Spanish');
|
||||
|
||||
-- end of added in 2.3
|
||||
|
|
Binary file not shown.
|
@ -833,11 +833,11 @@ msgstr "Password:"
|
|||
|
||||
#: airtime_mvc/application/forms/AddUser.php:40
|
||||
msgid "Firstname:"
|
||||
msgstr "Firstname:"
|
||||
msgstr "First name:"
|
||||
|
||||
#: airtime_mvc/application/forms/AddUser.php:47
|
||||
msgid "Lastname:"
|
||||
msgstr "Lastname:"
|
||||
msgstr "Last name:"
|
||||
|
||||
#: airtime_mvc/application/forms/AddUser.php:63
|
||||
msgid "Mobile Phone:"
|
||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Project-Id-Version: Airtime 2.3\n"
|
||||
"Report-Msgid-Bugs-To: http://forum.sourcefabric.org/\n"
|
||||
"POT-Creation-Date: 2012-11-29 11:44-0500\n"
|
||||
"PO-Revision-Date: 2012-12-03 21:49+0100\n"
|
||||
"PO-Revision-Date: 2012-12-08 13:56+0100\n"
|
||||
"Last-Translator: Albert Bruc <a.bruc@ab-ae.fr>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -899,7 +899,7 @@ msgstr "Invité"
|
|||
#: airtime_mvc/application/forms/AddUser.php:87
|
||||
#: airtime_mvc/application/controllers/LocaleController.php:307
|
||||
msgid "DJ"
|
||||
msgstr "DJ"
|
||||
msgstr "DeaJee"
|
||||
|
||||
#: airtime_mvc/application/forms/AddUser.php:88
|
||||
#: airtime_mvc/application/controllers/LocaleController.php:308
|
||||
|
@ -1469,7 +1469,7 @@ msgid ""
|
|||
"front-end widgets work.)"
|
||||
msgstr ""
|
||||
"Autoriser les sites internet à acceder aux informations de la Programmation ?"
|
||||
"%s (Activer cette option permetra aux widgets de fonctionner.)"
|
||||
"%s (Activer cette option permettra aux widgets de fonctionner.)"
|
||||
|
||||
#: airtime_mvc/application/forms/GeneralPreferences.php:49
|
||||
msgid "Disabled"
|
||||
|
@ -2098,16 +2098,16 @@ msgid ""
|
|||
"Check this box to automatically switch off Master/Show source upon source "
|
||||
"disconnection."
|
||||
msgstr ""
|
||||
"Cochez cette case pour arrête automatiquement la source Maître/Emission "
|
||||
"lors de la déconnexion."
|
||||
"Cochez cette case arrête automatiquement la source Maître/Emission lors de "
|
||||
"la déconnexion."
|
||||
|
||||
#: airtime_mvc/application/controllers/LocaleController.php:176
|
||||
msgid ""
|
||||
"Check this box to automatically switch on Master/Show source upon source "
|
||||
"connection."
|
||||
msgstr ""
|
||||
"Cochez cette case pour démarrer automatiquement la source Maître/Emission "
|
||||
"lors de la connexion."
|
||||
"Cochez cette case démarre automatiquement la source Maître/Emission lors de "
|
||||
"la connexion."
|
||||
|
||||
#: airtime_mvc/application/controllers/LocaleController.php:177
|
||||
msgid ""
|
||||
|
@ -2750,7 +2750,7 @@ msgstr "Lecture Programmée"
|
|||
|
||||
#: airtime_mvc/application/views/scripts/partialviews/header.phtml:54
|
||||
msgid "ON AIR"
|
||||
msgstr "EN DIRECT"
|
||||
msgstr "DIRECT"
|
||||
|
||||
#: airtime_mvc/application/views/scripts/partialviews/header.phtml:55
|
||||
msgid "Listen"
|
||||
|
@ -2879,7 +2879,7 @@ msgstr "Alors vous êtes prêt à démarrer!"
|
|||
#: airtime_mvc/application/views/scripts/dashboard/help.phtml:13
|
||||
#, php-format
|
||||
msgid "For more detailed help, read the %suser manual%s."
|
||||
msgstr "Pour une aide plus déraillée, lisez le %smanuel utilisateur%s."
|
||||
msgstr "Pour une aide plus détaillée, lisez le %smanuel utilisateur%s."
|
||||
|
||||
#: airtime_mvc/application/views/scripts/playlist/update.phtml:40
|
||||
msgid "Expand Static Block"
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -93,6 +93,10 @@ select {
|
|||
}
|
||||
/* Version Notification Ends*/
|
||||
|
||||
#current-user-container {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.override_help_icon, .icecast_metadata_help_icon {
|
||||
cursor: help;
|
||||
position: relative;
|
||||
|
@ -2935,3 +2939,19 @@ dd .stream-status {
|
|||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.edit-user-global dt {
|
||||
width: 90px;
|
||||
float: left;
|
||||
margin-top: 4px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.edit-user-global dd {
|
||||
width: 230px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.edit-user-global input {
|
||||
width: 170px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
.tipsy { font-size: 11px; position: absolute; padding: 5px; z-index: 100000; width: auto }
|
||||
.tipsy-inner { background-color: #000; color: #FFF; max-width: 300px; padding: 5px 8px 4px 5px; }
|
||||
|
||||
/* Rounded corners */
|
||||
.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }
|
||||
|
||||
/* Uncomment for shadow */
|
||||
/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/
|
||||
|
||||
.tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; }
|
||||
|
||||
/* Rules to colour arrows */
|
||||
.tipsy-arrow-n { border-bottom-color: #000; }
|
||||
.tipsy-arrow-s { border-top-color: #000; }
|
||||
.tipsy-arrow-e { border-left-color: #000; }
|
||||
.tipsy-arrow-w { border-right-color: #000; }
|
||||
|
||||
.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
||||
.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;}
|
||||
.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; }
|
||||
.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; }
|
||||
.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }
|
|
@ -441,7 +441,64 @@ function init() {
|
|||
});
|
||||
}
|
||||
|
||||
/* We never retrieve the user's password from the db
|
||||
* and when we call isValid($params) the form values are cleared
|
||||
* and repopulated with $params which does not have the password
|
||||
* field. Therefore, we fill the password field with 6 x's
|
||||
*/
|
||||
function setCurrentUserPseudoPassword() {
|
||||
$('#cu_password').val("xxxxxx");
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
if ($('#master-panel').length > 0)
|
||||
init();
|
||||
|
||||
var timer;
|
||||
|
||||
$('.tipsy').live('mouseover', function() {
|
||||
clearTimeout(timer);
|
||||
});
|
||||
|
||||
$('.tipsy').live('mouseout', function() {
|
||||
timer = setTimeout("$('#current-user').tipsy('hide')", 500);
|
||||
});
|
||||
|
||||
$('#current-user').bind('mouseover', function() {
|
||||
$.ajax({
|
||||
url: baseUrl+'/user/edit-user/format/json',
|
||||
success: function(json) {
|
||||
$('#current-user').tipsy({
|
||||
gravity: 'n',
|
||||
html: true,
|
||||
fade: true,
|
||||
opacity: 0.9,
|
||||
trigger: 'manual',
|
||||
title: function() {
|
||||
return json.html;
|
||||
}
|
||||
});
|
||||
},
|
||||
cache: false,
|
||||
complete: function() {
|
||||
$('#current-user').tipsy('show');
|
||||
setCurrentUserPseudoPassword();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$('#current-user').bind('mouseout', function() {
|
||||
timer = setTimeout("$('#current-user').tipsy('hide')", 500);
|
||||
});
|
||||
|
||||
$('#cu_save_user').live('click', function() {
|
||||
var data = $('#current-user-form').serialize();
|
||||
$.post(baseUrl+'/user/edit-user', {format: 'json', data: data}, function(data) {
|
||||
var json = $.parseJSON(data);
|
||||
$('.tipsy-inner').empty().append(json.html);
|
||||
setCurrentUserPseudoPassword();
|
||||
setTimeout(removeSuccessMsg, 5000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -915,7 +915,11 @@ var AIRTIME = (function(AIRTIME) {
|
|||
soundcloud.view.callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
// remove 'Add to smart block' option if the current
|
||||
// block is dynamic
|
||||
if ($('input:radio[name=sp_type]:checked').val() === "1") {
|
||||
delete oItems.pl_add;
|
||||
}
|
||||
items = oItems;
|
||||
}
|
||||
|
||||
|
|
|
@ -386,12 +386,28 @@ function setupEventListeners() {
|
|||
var json = $.parseJSON(data);
|
||||
$('#content').empty().append(json.html);
|
||||
setupEventListeners();
|
||||
setSliderForReplayGain();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setSliderForReplayGain(){
|
||||
$( "#slider-range-max" ).slider({
|
||||
range: "max",
|
||||
min: -10,
|
||||
max: 10,
|
||||
value: $("#rg_modifier_value").html(),
|
||||
slide: function( event, ui ) {
|
||||
$( "#replayGainModifier" ).val( ui.value );
|
||||
$("#rg_modifier_value").html(ui.value);
|
||||
}
|
||||
});
|
||||
$( "#replayGainModifier" ).val( $( "#slider-range-max" ).slider( "value" ) );
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
setupEventListeners();
|
||||
setSliderForReplayGain();
|
||||
});
|
||||
|
||||
|
|
|
@ -94,8 +94,83 @@ function populateUserTable() {
|
|||
|
||||
$(document).ready(function() {
|
||||
populateUserTable();
|
||||
|
||||
//assign user-rights and id to each user type option so we can
|
||||
//display user rights for each with tipsy tooltip
|
||||
$.each($('#type').children(), function(i, opt) {
|
||||
switch ($(this).val()) {
|
||||
case 'G':
|
||||
$(this).attr('id', 'user-type-G');
|
||||
$(this).attr('user-rights',
|
||||
$.i18n._('Guests can do the following:')+'<br><br>'+
|
||||
$.i18n._('View schedule')+'<br>'+
|
||||
$.i18n._('View show content')
|
||||
);
|
||||
break;
|
||||
case 'H':
|
||||
$(this).attr('id', 'user-type-H');
|
||||
$(this).attr('user-rights',
|
||||
$.i18n._('DJs can do the following:')+'<br><br>'+
|
||||
$.i18n._('View schedule')+'<br>'+
|
||||
$.i18n._('View show content')+'<br>'+
|
||||
$.i18n._('Manage assigned show content')+'<br>'+
|
||||
$.i18n._('Import media files')+'<br>'+
|
||||
$.i18n._('Create playlists, smart blocks, and webstreams')+'<br>'+
|
||||
$.i18n._('Manage their own library content')
|
||||
);
|
||||
break;
|
||||
case 'P':
|
||||
$(this).attr('id', 'user-type-P');
|
||||
$(this).attr('user-rights',
|
||||
$.i18n._('Progam Managers can do the following:')+'<br><br>'+
|
||||
$.i18n._('View schedule')+'<br>'+
|
||||
$.i18n._('View and manage show content')+'<br>'+
|
||||
$.i18n._('Schedule shows')+'<br>'+
|
||||
$.i18n._('Import media files')+'<br>'+
|
||||
$.i18n._('Create playlists, smart blocks, and webstreams')+'<br>'+
|
||||
$.i18n._('Manage all library content')
|
||||
);
|
||||
break;
|
||||
case 'A':
|
||||
$(this).attr('id', 'user-type-A');
|
||||
$(this).attr('user-rights',
|
||||
$.i18n._('Admins can do the following:')+'<br><br>'+
|
||||
$.i18n._('Manage preferences')+'<br>'+
|
||||
$.i18n._('Manage users')+'<br>'+
|
||||
$.i18n._('Manage watched folders')+'<br>'+
|
||||
$.i18n._('Send support feedback')+'<br>'+
|
||||
$.i18n._('View system status')+'<br>'+
|
||||
$.i18n._('Access playout history')+'<br>'+
|
||||
$.i18n._('View listener stats')+'<br>'+
|
||||
$.i18n._('View schedule')+'<br>'+
|
||||
$.i18n._('View and manage show content')+'<br>'+
|
||||
$.i18n._('Schedule shows')+'<br>'+
|
||||
$.i18n._('Import media files')+'<br>'+
|
||||
$.i18n._('Create playlists, smart blocks, and webstreams')+'<br>'+
|
||||
$.i18n._('Manage all library content')
|
||||
);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
$('#type').live("change", function(){
|
||||
//when the title changes on live tipsy tooltips the changes take
|
||||
//affect the next time tipsy is shown so we need to hide and re-show it
|
||||
$(this).tipsy('hide').tipsy('show');
|
||||
});
|
||||
|
||||
//$('#user_details').hide();
|
||||
$('#type').tipsy({
|
||||
gravity: 'w',
|
||||
html: true,
|
||||
opacity: 0.9,
|
||||
trigger: 'manual',
|
||||
live: true,
|
||||
title: function() {
|
||||
return $('#user-type-'+$(this).val()).attr('user-rights');
|
||||
}
|
||||
});
|
||||
|
||||
$('#type').tipsy('show');
|
||||
|
||||
var newUser = {login:"", first_name:"", last_name:"", type:"G", id:""};
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"sEmptyTable": "No data available in table",
|
||||
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
|
||||
"sInfoEmpty": "Showing 0 to 0 of 0 entries",
|
||||
"sInfoFiltered": "(filtered from _MAX_ total entries)",
|
||||
"sInfoPostFix": "",
|
||||
"sInfoThousands": ",",
|
||||
"sLengthMenu": "Show _MENU_",
|
||||
"sLoadingRecords": "Loading...",
|
||||
"sProcessing": "Processing...",
|
||||
"sSearch": "",
|
||||
"sZeroRecords": "No matching records found",
|
||||
"oPaginate": {
|
||||
"sFirst": "First",
|
||||
"sLast": "Last",
|
||||
"sNext": "Next",
|
||||
"sPrevious": "Previous"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": activate to sort column ascending",
|
||||
"sSortDescending": ": activate to sort column descending"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"sProcessing": "Подождите...",
|
||||
"sLengthMenu": "Показать _MENU_ записей",
|
||||
"sZeroRecords": "Записи отсутствуют.",
|
||||
"sInfo": "Записи с _START_ до _END_ из _TOTAL_ записей",
|
||||
"sInfoEmpty": "Записи с 0 до 0 из 0 записей",
|
||||
"sInfoFiltered": "(отфильтровано из _MAX_ записей)",
|
||||
"sInfoPostFix": "",
|
||||
"sSearch": "",
|
||||
"sUrl": "",
|
||||
"oPaginate": {
|
||||
"sFirst": "Первая",
|
||||
"sPrevious": "Предыдущая",
|
||||
"sNext": "Следующая",
|
||||
"sLast": "Последняя"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// English - US
|
||||
plupload.addI18n({
|
||||
'Select files' : 'Select files',
|
||||
'Add files to the upload queue and click the start button.' : 'Add files to the upload queue and click the start button.',
|
||||
'Filename' : 'Filename',
|
||||
'Status' : 'Status',
|
||||
'Size' : 'Size',
|
||||
'Add files' : 'Add files',
|
||||
'Stop current upload' : 'Stop current upload',
|
||||
'Start uploading queue' : 'Start uploading queue',
|
||||
'Uploaded %d/%d files': 'Uploaded %d/%d files',
|
||||
'N/A' : 'N/A',
|
||||
'Drag files here.' : 'Drag files here.',
|
||||
'File extension error.': 'File extension error.',
|
||||
'File size error.': 'File size error.',
|
||||
'Init error.': 'Init error.',
|
||||
'HTTP Error.': 'HTTP Error.',
|
||||
'Security error.': 'Security error.',
|
||||
'Generic error.': 'Generic error.',
|
||||
'IO error.': 'IO error.',
|
||||
'Stop Upload': 'Stop Upload',
|
||||
'Add Files': 'Add Files',
|
||||
'Start Upload': 'Start Upload',
|
||||
'Start upload': 'Start upload',
|
||||
'%d files queued': '%d files queued'
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
// Russian
|
||||
plupload.addI18n({
|
||||
'Select files' : 'Выберите файлы',
|
||||
'Add files to the upload queue and click the start button.' : 'Добавьте файлы в очередь и нажмите кнопку "Загрузить файлы".',
|
||||
'Filename' : 'Имя файла',
|
||||
'Status' : 'Статус',
|
||||
'Size' : 'Размер',
|
||||
'Add files' : 'Добавить файлы',
|
||||
'Stop current upload' : 'Остановить загрузку',
|
||||
'Start upload' : 'Загрузить файлы',
|
||||
'Uploaded %d/%d files': 'Загружено %d из %d файлов',
|
||||
'N/A' : 'N/D',
|
||||
'Drag files here.' : 'Перетащите файлы сюда.',
|
||||
'File extension error.': 'Неправильное расширение файла.',
|
||||
'File size error.': 'Неправильный размер файла.',
|
||||
'Init error.': 'Ошибка инициализации.',
|
||||
'HTTP Error.': 'Ошибка HTTP.',
|
||||
'Security error.': 'Ошибка безопасности.',
|
||||
'Generic error.': 'Общая ошибка.',
|
||||
'IO error.': 'Ошибка ввода-вывода.'
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
Before overwriting jquery.tipsy.js, please note we have changed a few lines to
|
||||
support manual triggering with live tipsy tooltips
|
||||
|
||||
|
||||
denise@denise-DX4860:~/airtime/airtime_mvc/public/js/tipsy$ diff -u jquery.tipsy_orig.js jquery.tipsy.js
|
||||
--- jquery.tipsy_orig.js 2012-12-13 12:03:48.780751104 -0500
|
||||
+++ jquery.tipsy.js 2012-12-13 12:08:15.564761493 -0500
|
||||
@@ -173,12 +173,10 @@
|
||||
|
||||
if (!options.live) this.each(function() { get(this); });
|
||||
|
||||
- if (options.trigger != 'manual') {
|
||||
- var binder = options.live ? 'live' : 'bind',
|
||||
- eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
|
||||
- eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
|
||||
- this[binder](eventIn, enter)[binder](eventOut, leave);
|
||||
- }
|
||||
+ var binder = options.live ? 'live' : 'bind',
|
||||
+ eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
|
||||
+ eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
|
||||
+ this[binder](eventIn, enter)[binder](eventOut, leave);
|
||||
|
||||
return this;
|
|
@ -0,0 +1,256 @@
|
|||
// tipsy, facebook style tooltips for jquery
|
||||
// version 1.0.0a
|
||||
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
|
||||
// released under the MIT license
|
||||
|
||||
(function($) {
|
||||
|
||||
function maybeCall(thing, ctx) {
|
||||
return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
|
||||
};
|
||||
|
||||
function isElementInDOM(ele) {
|
||||
while (ele = ele.parentNode) {
|
||||
if (ele == document) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
function Tipsy(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = options;
|
||||
this.enabled = true;
|
||||
this.fixTitle();
|
||||
};
|
||||
|
||||
Tipsy.prototype = {
|
||||
show: function() {
|
||||
var title = this.getTitle();
|
||||
if (title && this.enabled) {
|
||||
var $tip = this.tip();
|
||||
|
||||
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
|
||||
$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
|
||||
$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);
|
||||
|
||||
var pos = $.extend({}, this.$element.offset(), {
|
||||
width: this.$element[0].offsetWidth,
|
||||
height: this.$element[0].offsetHeight
|
||||
});
|
||||
|
||||
var actualWidth = $tip[0].offsetWidth,
|
||||
actualHeight = $tip[0].offsetHeight,
|
||||
gravity = maybeCall(this.options.gravity, this.$element[0]);
|
||||
|
||||
var tp;
|
||||
switch (gravity.charAt(0)) {
|
||||
case 'n':
|
||||
tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
|
||||
break;
|
||||
case 's':
|
||||
tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
|
||||
break;
|
||||
case 'e':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
|
||||
break;
|
||||
case 'w':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
|
||||
break;
|
||||
}
|
||||
|
||||
if (gravity.length == 2) {
|
||||
if (gravity.charAt(1) == 'w') {
|
||||
tp.left = pos.left + pos.width / 2 - 15;
|
||||
} else {
|
||||
tp.left = pos.left + pos.width / 2 - actualWidth + 15;
|
||||
}
|
||||
}
|
||||
|
||||
$tip.css(tp).addClass('tipsy-' + gravity);
|
||||
$tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
|
||||
if (this.options.className) {
|
||||
$tip.addClass(maybeCall(this.options.className, this.$element[0]));
|
||||
}
|
||||
|
||||
if (this.options.fade) {
|
||||
$tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
|
||||
} else {
|
||||
$tip.css({visibility: 'visible', opacity: this.options.opacity});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.options.fade) {
|
||||
this.tip().stop().fadeOut(function() { $(this).remove(); });
|
||||
} else {
|
||||
this.tip().remove();
|
||||
}
|
||||
},
|
||||
|
||||
fixTitle: function() {
|
||||
var $e = this.$element;
|
||||
if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
|
||||
$e.attr('original-title', $e.attr('title') || '').removeAttr('title');
|
||||
}
|
||||
},
|
||||
|
||||
getTitle: function() {
|
||||
var title, $e = this.$element, o = this.options;
|
||||
this.fixTitle();
|
||||
var title, o = this.options;
|
||||
if (typeof o.title == 'string') {
|
||||
title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
|
||||
} else if (typeof o.title == 'function') {
|
||||
title = o.title.call($e[0]);
|
||||
}
|
||||
title = ('' + title).replace(/(^\s*|\s*$)/, "");
|
||||
return title || o.fallback;
|
||||
},
|
||||
|
||||
tip: function() {
|
||||
if (!this.$tip) {
|
||||
this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>');
|
||||
this.$tip.data('tipsy-pointee', this.$element[0]);
|
||||
}
|
||||
return this.$tip;
|
||||
},
|
||||
|
||||
validate: function() {
|
||||
if (!this.$element[0].parentNode) {
|
||||
this.hide();
|
||||
this.$element = null;
|
||||
this.options = null;
|
||||
}
|
||||
},
|
||||
|
||||
enable: function() { this.enabled = true; },
|
||||
disable: function() { this.enabled = false; },
|
||||
toggleEnabled: function() { this.enabled = !this.enabled; }
|
||||
};
|
||||
|
||||
$.fn.tipsy = function(options) {
|
||||
|
||||
if (options === true) {
|
||||
return this.data('tipsy');
|
||||
} else if (typeof options == 'string') {
|
||||
var tipsy = this.data('tipsy');
|
||||
if (tipsy) tipsy[options]();
|
||||
return this;
|
||||
}
|
||||
|
||||
options = $.extend({}, $.fn.tipsy.defaults, options);
|
||||
|
||||
function get(ele) {
|
||||
var tipsy = $.data(ele, 'tipsy');
|
||||
if (!tipsy) {
|
||||
tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
|
||||
$.data(ele, 'tipsy', tipsy);
|
||||
}
|
||||
return tipsy;
|
||||
}
|
||||
|
||||
function enter() {
|
||||
var tipsy = get(this);
|
||||
tipsy.hoverState = 'in';
|
||||
if (options.delayIn == 0) {
|
||||
tipsy.show();
|
||||
} else {
|
||||
tipsy.fixTitle();
|
||||
setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
|
||||
}
|
||||
};
|
||||
|
||||
function leave() {
|
||||
var tipsy = get(this);
|
||||
tipsy.hoverState = 'out';
|
||||
if (options.delayOut == 0) {
|
||||
tipsy.hide();
|
||||
} else {
|
||||
setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
|
||||
}
|
||||
};
|
||||
|
||||
if (!options.live) this.each(function() { get(this); });
|
||||
|
||||
var binder = options.live ? 'live' : 'bind',
|
||||
eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
|
||||
eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
|
||||
this[binder](eventIn, enter)[binder](eventOut, leave);
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
$.fn.tipsy.defaults = {
|
||||
className: null,
|
||||
delayIn: 0,
|
||||
delayOut: 0,
|
||||
fade: false,
|
||||
fallback: '',
|
||||
gravity: 'n',
|
||||
html: false,
|
||||
live: false,
|
||||
offset: 0,
|
||||
opacity: 0.8,
|
||||
title: 'title',
|
||||
trigger: 'hover'
|
||||
};
|
||||
|
||||
$.fn.tipsy.revalidate = function() {
|
||||
$('.tipsy').each(function() {
|
||||
var pointee = $.data(this, 'tipsy-pointee');
|
||||
if (!pointee || !isElementInDOM(pointee)) {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Overwrite this method to provide options on a per-element basis.
|
||||
// For example, you could store the gravity in a 'tipsy-gravity' attribute:
|
||||
// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
|
||||
// (remember - do not modify 'options' in place!)
|
||||
$.fn.tipsy.elementOptions = function(ele, options) {
|
||||
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
|
||||
};
|
||||
|
||||
$.fn.tipsy.autoNS = function() {
|
||||
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
|
||||
};
|
||||
|
||||
$.fn.tipsy.autoWE = function() {
|
||||
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
|
||||
};
|
||||
|
||||
/**
|
||||
* yields a closure of the supplied parameters, producing a function that takes
|
||||
* no arguments and is suitable for use as an autogravity function like so:
|
||||
*
|
||||
* @param margin (int) - distance from the viewable region edge that an
|
||||
* element should be before setting its tooltip's gravity to be away
|
||||
* from that edge.
|
||||
* @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
|
||||
* if there are no viewable region edges effecting the tooltip's
|
||||
* gravity. It will try to vary from this minimally, for example,
|
||||
* if 'sw' is preferred and an element is near the right viewable
|
||||
* region edge, but not the top edge, it will set the gravity for
|
||||
* that element's tooltip to be 'se', preserving the southern
|
||||
* component.
|
||||
*/
|
||||
$.fn.tipsy.autoBounds = function(margin, prefer) {
|
||||
return function() {
|
||||
var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
|
||||
boundTop = $(document).scrollTop() + margin,
|
||||
boundLeft = $(document).scrollLeft() + margin,
|
||||
$this = $(this);
|
||||
|
||||
if ($this.offset().top < boundTop) dir.ns = 'n';
|
||||
if ($this.offset().left < boundLeft) dir.ew = 'w';
|
||||
if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
|
||||
if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';
|
||||
|
||||
return dir.ns + (dir.ew ? dir.ew : '');
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
|
@ -0,0 +1,258 @@
|
|||
// tipsy, facebook style tooltips for jquery
|
||||
// version 1.0.0a
|
||||
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
|
||||
// released under the MIT license
|
||||
|
||||
(function($) {
|
||||
|
||||
function maybeCall(thing, ctx) {
|
||||
return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
|
||||
};
|
||||
|
||||
function isElementInDOM(ele) {
|
||||
while (ele = ele.parentNode) {
|
||||
if (ele == document) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
function Tipsy(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = options;
|
||||
this.enabled = true;
|
||||
this.fixTitle();
|
||||
};
|
||||
|
||||
Tipsy.prototype = {
|
||||
show: function() {
|
||||
var title = this.getTitle();
|
||||
if (title && this.enabled) {
|
||||
var $tip = this.tip();
|
||||
|
||||
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
|
||||
$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
|
||||
$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);
|
||||
|
||||
var pos = $.extend({}, this.$element.offset(), {
|
||||
width: this.$element[0].offsetWidth,
|
||||
height: this.$element[0].offsetHeight
|
||||
});
|
||||
|
||||
var actualWidth = $tip[0].offsetWidth,
|
||||
actualHeight = $tip[0].offsetHeight,
|
||||
gravity = maybeCall(this.options.gravity, this.$element[0]);
|
||||
|
||||
var tp;
|
||||
switch (gravity.charAt(0)) {
|
||||
case 'n':
|
||||
tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
|
||||
break;
|
||||
case 's':
|
||||
tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
|
||||
break;
|
||||
case 'e':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
|
||||
break;
|
||||
case 'w':
|
||||
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
|
||||
break;
|
||||
}
|
||||
|
||||
if (gravity.length == 2) {
|
||||
if (gravity.charAt(1) == 'w') {
|
||||
tp.left = pos.left + pos.width / 2 - 15;
|
||||
} else {
|
||||
tp.left = pos.left + pos.width / 2 - actualWidth + 15;
|
||||
}
|
||||
}
|
||||
|
||||
$tip.css(tp).addClass('tipsy-' + gravity);
|
||||
$tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
|
||||
if (this.options.className) {
|
||||
$tip.addClass(maybeCall(this.options.className, this.$element[0]));
|
||||
}
|
||||
|
||||
if (this.options.fade) {
|
||||
$tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
|
||||
} else {
|
||||
$tip.css({visibility: 'visible', opacity: this.options.opacity});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.options.fade) {
|
||||
this.tip().stop().fadeOut(function() { $(this).remove(); });
|
||||
} else {
|
||||
this.tip().remove();
|
||||
}
|
||||
},
|
||||
|
||||
fixTitle: function() {
|
||||
var $e = this.$element;
|
||||
if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
|
||||
$e.attr('original-title', $e.attr('title') || '').removeAttr('title');
|
||||
}
|
||||
},
|
||||
|
||||
getTitle: function() {
|
||||
var title, $e = this.$element, o = this.options;
|
||||
this.fixTitle();
|
||||
var title, o = this.options;
|
||||
if (typeof o.title == 'string') {
|
||||
title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
|
||||
} else if (typeof o.title == 'function') {
|
||||
title = o.title.call($e[0]);
|
||||
}
|
||||
title = ('' + title).replace(/(^\s*|\s*$)/, "");
|
||||
return title || o.fallback;
|
||||
},
|
||||
|
||||
tip: function() {
|
||||
if (!this.$tip) {
|
||||
this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>');
|
||||
this.$tip.data('tipsy-pointee', this.$element[0]);
|
||||
}
|
||||
return this.$tip;
|
||||
},
|
||||
|
||||
validate: function() {
|
||||
if (!this.$element[0].parentNode) {
|
||||
this.hide();
|
||||
this.$element = null;
|
||||
this.options = null;
|
||||
}
|
||||
},
|
||||
|
||||
enable: function() { this.enabled = true; },
|
||||
disable: function() { this.enabled = false; },
|
||||
toggleEnabled: function() { this.enabled = !this.enabled; }
|
||||
};
|
||||
|
||||
$.fn.tipsy = function(options) {
|
||||
|
||||
if (options === true) {
|
||||
return this.data('tipsy');
|
||||
} else if (typeof options == 'string') {
|
||||
var tipsy = this.data('tipsy');
|
||||
if (tipsy) tipsy[options]();
|
||||
return this;
|
||||
}
|
||||
|
||||
options = $.extend({}, $.fn.tipsy.defaults, options);
|
||||
|
||||
function get(ele) {
|
||||
var tipsy = $.data(ele, 'tipsy');
|
||||
if (!tipsy) {
|
||||
tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
|
||||
$.data(ele, 'tipsy', tipsy);
|
||||
}
|
||||
return tipsy;
|
||||
}
|
||||
|
||||
function enter() {
|
||||
var tipsy = get(this);
|
||||
tipsy.hoverState = 'in';
|
||||
if (options.delayIn == 0) {
|
||||
tipsy.show();
|
||||
} else {
|
||||
tipsy.fixTitle();
|
||||
setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
|
||||
}
|
||||
};
|
||||
|
||||
function leave() {
|
||||
var tipsy = get(this);
|
||||
tipsy.hoverState = 'out';
|
||||
if (options.delayOut == 0) {
|
||||
tipsy.hide();
|
||||
} else {
|
||||
setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
|
||||
}
|
||||
};
|
||||
|
||||
if (!options.live) this.each(function() { get(this); });
|
||||
|
||||
if (options.trigger != 'manual') {
|
||||
var binder = options.live ? 'live' : 'bind',
|
||||
eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
|
||||
eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
|
||||
this[binder](eventIn, enter)[binder](eventOut, leave);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
};
|
||||
|
||||
$.fn.tipsy.defaults = {
|
||||
className: null,
|
||||
delayIn: 0,
|
||||
delayOut: 0,
|
||||
fade: false,
|
||||
fallback: '',
|
||||
gravity: 'n',
|
||||
html: false,
|
||||
live: false,
|
||||
offset: 0,
|
||||
opacity: 0.8,
|
||||
title: 'title',
|
||||
trigger: 'hover'
|
||||
};
|
||||
|
||||
$.fn.tipsy.revalidate = function() {
|
||||
$('.tipsy').each(function() {
|
||||
var pointee = $.data(this, 'tipsy-pointee');
|
||||
if (!pointee || !isElementInDOM(pointee)) {
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Overwrite this method to provide options on a per-element basis.
|
||||
// For example, you could store the gravity in a 'tipsy-gravity' attribute:
|
||||
// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
|
||||
// (remember - do not modify 'options' in place!)
|
||||
$.fn.tipsy.elementOptions = function(ele, options) {
|
||||
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
|
||||
};
|
||||
|
||||
$.fn.tipsy.autoNS = function() {
|
||||
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
|
||||
};
|
||||
|
||||
$.fn.tipsy.autoWE = function() {
|
||||
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
|
||||
};
|
||||
|
||||
/**
|
||||
* yields a closure of the supplied parameters, producing a function that takes
|
||||
* no arguments and is suitable for use as an autogravity function like so:
|
||||
*
|
||||
* @param margin (int) - distance from the viewable region edge that an
|
||||
* element should be before setting its tooltip's gravity to be away
|
||||
* from that edge.
|
||||
* @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
|
||||
* if there are no viewable region edges effecting the tooltip's
|
||||
* gravity. It will try to vary from this minimally, for example,
|
||||
* if 'sw' is preferred and an element is near the right viewable
|
||||
* region edge, but not the top edge, it will set the gravity for
|
||||
* that element's tooltip to be 'se', preserving the southern
|
||||
* component.
|
||||
*/
|
||||
$.fn.tipsy.autoBounds = function(margin, prefer) {
|
||||
return function() {
|
||||
var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
|
||||
boundTop = $(document).scrollTop() + margin,
|
||||
boundLeft = $(document).scrollLeft() + margin,
|
||||
$this = $(this);
|
||||
|
||||
if ($this.offset().top < boundTop) dir.ns = 'n';
|
||||
if ($this.offset().left < boundLeft) dir.ew = 'w';
|
||||
if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
|
||||
if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';
|
||||
|
||||
return dir.ns + (dir.ew ? dir.ew : '');
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
12
changelog
12
changelog
|
@ -1,3 +1,15 @@
|
|||
2.2.1 - December 4th, 2012
|
||||
* Bug fixes
|
||||
* Improved fades between webstreams
|
||||
* Fix webstreams disconnecting occasionally
|
||||
* Put 'and' and 'or' connectors between smart blocks
|
||||
* Fix inability to preview webstreams in the Now Playing page on some
|
||||
browsers
|
||||
* Fix airtime-import script failing on FLAC files
|
||||
* Fix DJ's being able to delete files they don't own
|
||||
* Add support for 'x-scpls' webstream playlist types
|
||||
* Fix media-monitor requiring a restart for initial import.
|
||||
|
||||
2.2.0 - October 25th, 2012
|
||||
* New features
|
||||
* Smart Playlists
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#! /bin/bash
|
||||
|
||||
cd ..
|
||||
|
||||
#generate a new .po file
|
||||
#this will generate a file called messages.po
|
||||
find . -iname "*.phtml" -o -name "*.php" | xargs xgettext -L php
|
||||
|
||||
#merge the new messages from messages.po into each existing .po file
|
||||
#this will generate new .po files
|
||||
find ./airtime_mvc/locale/ -name "*.po" -exec msgmerge -N -U --no-wrap "{}" messages.po \;
|
||||
|
||||
#delete the old .po files
|
||||
find ./airtime_mvc/locale/ -name "*.po~" -delete
|
|
@ -154,6 +154,9 @@ def walk_supported(directory, clean_empties=False):
|
|||
that support the extensions we are considering. When clean_empties
|
||||
is True we recursively delete empty directories left over in
|
||||
directory after the walk. """
|
||||
if directory is None:
|
||||
return
|
||||
|
||||
for root, dirs, files in os.walk(directory):
|
||||
full_paths = ( os.path.join(root, name) for name in files
|
||||
if is_file_supported(name) )
|
||||
|
@ -162,8 +165,7 @@ def walk_supported(directory, clean_empties=False):
|
|||
|
||||
|
||||
def file_locked(path):
|
||||
cmd = "lsof %s" % (pipes.quote(path))
|
||||
f = Popen(cmd, shell=True, stdout=PIPE).stdout
|
||||
f = Popen(["lsof", path], stdout=PIPE).stdout
|
||||
return bool(f.readlines())
|
||||
|
||||
def magic_move(old, new, after_dir_make=lambda : None):
|
||||
|
|
Loading…
Reference in New Issue