Merge branch 'saas-dev' into saas-dev-publishing

Conflicts:
	airtime_mvc/public/css/dashboard.css
	airtime_mvc/public/css/styles.css
	airtime_mvc/public/js/airtime/library/library.js
	airtime_mvc/public/js/airtime/library/spl.js
This commit is contained in:
Duncan Sommerville 2015-09-30 16:26:02 -04:00
commit c3c4abdd0c
31 changed files with 427 additions and 206 deletions

View File

@ -21,6 +21,8 @@ define('ABOUT_AIRTIME_URL' , 'https://www.airtime.pro/support/');
define('AIRTIME_TRANSIFEX_URL' , 'https://www.transifex.com/projects/p/airtime/');
define('WHMCS_PASSWORD_RESET_URL' , 'https://account.sourcefabric.com/pwreset.php');
define('SUPPORT_TICKET_URL' , 'https://sourcefabricberlin.zendesk.com/hc/en-us/requests/new');
define('UI_REVAMP_EMBED_URL' , 'https://www.youtube.com/embed/nqpNnCKGluY');
define('UI_REVAMP_YOUTUBE_URL' , 'https://www.youtube.com/watch?v=nqpNnCKGluY&feature=youtu.be');
define('LICENSE_VERSION' , 'GNU AGPL v.3');
define('LICENSE_URL' , 'http://www.gnu.org/licenses/agpl-3.0-standalone.html');

View File

@ -172,6 +172,11 @@ $pages = array(
'label' => _(sprintf("Help Translate %s", PRODUCT_NAME)),
'uri' => AIRTIME_TRANSIFEX_URL,
'target' => "_blank"
),
array(
'label' => _('What\'s New?'),
'uri' => UI_REVAMP_YOUTUBE_URL,
'target' => "_blank"
)
)
),

View File

@ -426,8 +426,9 @@ class LocaleController extends Zend_Controller_Action
"Next",
"Previous",
": activate to sort column ascending",
": activate to sort column descending"
": activate to sort column descending",
//End of datatables
"Welcome to the new Airtime Pro!" => _("Welcome to the new Airtime Pro!")
);
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);

View File

@ -207,10 +207,6 @@ class PreferenceController extends Zend_Controller_Action
$values["s4_data"] = $s4_data;
if ($form->isValid($values)) {
$values['icecast_vorbis_metadata'] = $form->getValue('icecast_vorbis_metadata');
$values['streamFormat'] = $form->getValue('streamFormat');
Application_Model_StreamSetting::setStreamSetting($values);
/* If the admin password values are empty then we should not

View File

@ -55,6 +55,7 @@ class ShowbuilderController extends Zend_Controller_Action
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/main_builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
// MEDIA BUILDER
$this->view->headScript()->appendFile($baseUrl.'js/js-timezone-detect/jstz-1.0.4.min.js','text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/library/spl.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/library/podcast.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/library/publish.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');
@ -84,6 +85,8 @@ class ShowbuilderController extends Zend_Controller_Action
$end = DateTime::createFromFormat("U", $to, $utcTimezone);
$end->setTimezone($displayTimeZone);
$this->checkAndShowSetupPopup($request);
$form = new Application_Form_ShowBuilder();
$form->populate(array(
'sb_date_start' => $start->format("Y-m-d"),

View File

@ -63,12 +63,16 @@ class WebstreamController extends Zend_Controller_Action
if (!$isAdminOrPM && $webstream->getDbCreatorId() != $user->getId()) {
$this->view->objType = "webstream";
$this->view->type = "webstream";
$this->view->obj = $obj;
$this->view->id = $id;
$this->view->html = $this->view->render('playlist/permission-denied.phtml');
return;
}
$this->view->obj = $obj;
$this->view->type = "webstream";
$this->view->id = $id;
$this->view->action = "edit";
$this->view->html = $this->view->render('webstream/webstream.phtml');
}

View File

@ -85,7 +85,11 @@ class Application_Form_ShowBuilder extends Zend_Form_SubForm
private function getShowNames()
{
$showNames = array("0" => _("Filter by Show"));
$user = Application_Model_User::getCurrentUser();
$showNames = array("0" => _("Filter by Show"));
if ($user->getType() === 'H') {
$showNames["-1"] = _("My Shows");
}
$shows = CcShowQuery::create()
->setFormatter(ModelCriteria::FORMAT_ON_DEMAND)

View File

@ -167,6 +167,56 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
</div>
</div>
</script>
<?php
// Show users the What's New dialog if they haven't seen it yet
// TODO: If you're updating this, be sure to update defaultdata! (Suboptimal, is there a better way?)
if (!Application_Model_Preference::getWhatsNewDialogViewed()) {
?>
<div id="whatsnew">
<div>
<div id="whatsnew_video">
<iframe width="560" height="315" src="<?php echo UI_REVAMP_EMBED_URL ?>" frameborder="0" allowfullscreen></iframe>
</div>
<h2><?php echo _("Airtime Pro has a new look!"); ?></h2>
<p><?php echo _("Your favorite features are now even easier to use - and we've even
added a few new ones! Check out the video above or read on to find out more."); ?></p>
<ul>
<li><?php echo _("Our new Dashboard view now has a powerful tabbed editing interface, so updating your tracks and playlists
is easier than ever."); ?></li>
<li><?php echo _("We've streamlined the Airtime interface to make navigation easier. With the most important tools
just a click away, you'll be on air and hands-free in no time."); ?></li>
<li><?php echo _("Got a huge music library? No problem! With the new Upload page, you can drag and drop whole folders to our private cloud."); ?></li>
<li><?php echo _("The new Airtime is smoother, sleeker, and faster - on even more devices! We're committed to improving the Airtime
experience, no matter how you're connected."); ?></li>
</ul>
</div>
<button id="whatsnew_close" class="btn btn-new">OK, got it!</button>
</div>
<script>
$(document).ready(function() {
var whatsnew = $("#whatsnew");
whatsnew.dialog({
title: $.i18n._("Welcome to the new Airtime Pro!"),
width: "auto",
height: "auto",
modal: true,
resizable: false,
close: function() {
$(this).dialog('destroy').remove();
}
});
$("#whatsnew_close").on("click", function() {
whatsnew.dialog("close");
});
});
</script>
<?php
Application_Model_Preference::setWhatsNewDialogViewed(true);
}
?>
</body>
</html>

View File

@ -138,7 +138,13 @@ class Application_Model_Preference
$st->execute();
}
private static function getValue($key, $isUserValue = false)
/**
* @param string $key the preference key string
* @param bool|false $isUserValue select the preference for the current user
* @param bool|false $forceDefault only look for default (no user ID) values
* @return mixed the preference value
*/
private static function getValue($key, $isUserValue = false, $forceDefault = false)
{
$cache = new Cache();
@ -164,6 +170,8 @@ class Application_Model_Preference
if ($isUserValue) {
$sql .= " AND subjid = :id";
$paramMap[':id'] = $userId;
} else if ($forceDefault) {
$sql .= " AND subjid IS NULL";
}
$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN);
@ -1478,4 +1486,20 @@ class Application_Model_Preference
{
self::setValue("lang_tz_setup_complete", $value);
}
public static function getWhatsNewDialogViewed()
{
$val = self::getValue("whats_new_dialog_viewed", true);
if (empty($val)) {
// Check the default (no user ID) value if the user value is empty
// This is so that new stations won't see the popup
$val = self::getValue("whats_new_dialog_viewed", false, true);
}
return empty($val) ? false : $val;
}
public static function setWhatsNewDialogViewed($value)
{
self::setValue("whats_new_dialog_viewed", $value, true);
}
}

View File

@ -1035,7 +1035,11 @@ SQL;
self::createStreamScheduleEvent($data, $item, $media_id, $uri);
}
else {
throw new Exception("Unknown schedule type: ".print_r($item, true));
//throw new Exception("Unknown schedule type: ".print_r($item, true));
//It's currently possible (and normal) to get cc_schedule rows without
//a file_id or stream_id. If you're using linked shows, placeholder rows can be put
//in the schedule when you cancel a track or delete stuff, so we should not throw an exception
//here and instead just ignore it.
}
}

View File

@ -1044,17 +1044,31 @@ SQL;
$event["nowPlaying"] = false;
}
//event colouring
if ($show["color"] != "") {
$event["textColor"] = "#".$show["color"];
}
if (!empty($show["background_color"])) {
$event["color"] = "#" . $show["background_color"];
} else {
$event["color"] = "#" . self::getDefaultBackgroundColor($startsDT);//DEFAULT_SHOW_COLOR;
}
//event colouring
if ($show["color"] != "") {
$event["textColor"] = "#".$show["color"];
} else {
$bg = $event["color"];
//Calculate the text colour (black or white) based on the brightness of the background.
$r = intval(substr($bg, 1, 2), 16);
$g = intval(substr($bg, 3, 2), 16);
$b = intval(substr($bg, 5, 2), 16);
$brightness = 0.299*floatval($r) + 0.587*floatval($g) + 0.114*floatval($b);
if ($brightness > 130) {
$event["textColor"] = "#000000";
} else {
$event["textColor"] = "#fcfcfc";
}
}
foreach ($options as $key => $value) {
$event[$key] = $value;
}
@ -1067,12 +1081,33 @@ SQL;
/** Get a palettized colour for the show. */
private static function getDefaultBackgroundColor($date) {
$basePalette = ['A22BE8', '2FFF8D', 'FF743C', '2ED4FF', 'E8D82B'];
// 'B23F11', 'FF7E4A', 'FF6C31'
/*
$palette = [['42d5a1', '56bd99', '65ab93', '7b938b'],
['42a4d5', '569bbd', '6594ab', '7b8b93'],
['4264d5', '566fbd', '6576ab', '7b8193']];
*/
$palette = [];
for ($baseColorIdx = 0; $baseColorIdx < count($basePalette); $baseColorIdx++) {
$dayPalette = [];
for ($shade = 0.0; $shade < 0.8; $shade += 0.1) {
$origColour = $basePalette[$baseColorIdx];
$r = intval(substr($origColour, 0, 2), 16);
$g = intval(substr($origColour, 2, 2), 16);
$b = intval(substr($origColour, 4, 2), 16);
$r = floatval($r) * (1.0 - $shade);
$g = floatval($g) * (1.0 - $shade);
$b = floatval($b) * (1.0 - $shade);
$color = sprintf("%02x%02x%02x", $r, $g, $b);
array_push($dayPalette, $color);
}
array_push($palette, $dayPalette);
}
//$hashValue = (md5($date->format('d'))[0] % $cols) + ((intval($date->format('h'))/24) % $rows);
$row = intval($date->format('d')) % sizeof($palette);
$row = intval($date->format('w')) % sizeof($palette);
$foo = $date->format('H');
$col = intval(intval($date->format('H'))/24.0 * sizeof($palette[0]));
//$color = $palette[$hashValue % sizeof($palette)];

View File

@ -154,7 +154,9 @@ class Podcast extends BasePodcast
"guid" => $item->get_id(),
"ingested" => in_array($item->get_id(), $episodeIds),
"title" => $item->get_title(),
"author" => $item->get_author()->get_name(),
// From the RSS spec best practices:
// 'An item's author element provides the e-mail address of the person who wrote the item'
"author" => $item->get_author()->get_email(),
"description" => $item->get_description(),
"pub_date" => $item->get_date("Y-m-d H:i:s"),
"link" => $item->get_link(),

View File

@ -9,8 +9,8 @@
<?php echo $this->element->getElement('sb_show_filter') ?>
<?php if ($this->element->getElement('sb_my_shows')):?>
<label><?php echo $this->element->getElement('sb_my_shows')->getLabel(); ?></label>
<?php echo $this->element->getElement('sb_my_shows'); ?>
<?php endif;?>
<!-- --><?php //if ($this->element->getElement('sb_my_shows')):?>
<!-- <label>--><?php //echo $this->element->getElement('sb_my_shows')->getLabel(); ?><!--</label>-->
<!-- --><?php //echo $this->element->getElement('sb_my_shows'); ?>
<!-- --><?php //endif;?>
</div>

View File

@ -34,3 +34,4 @@
</div>
<?php echo $this->dialog ?>
<?php echo $this->lang_tz_popup_form; ?>

View File

@ -385,3 +385,6 @@ CREATE UNIQUE INDEX cc_pref_key_idx ON cc_pref (keystr) WHERE subjid IS NULL;
ANALYZE cc_pref; -- this validates the new partial index
--end added in 2.5.14
-- For now, just needs to be truthy - to be updated later; we should find a better way to implement this...
INSERT INTO cc_pref("keystr", "valstr") VALUES('whats_new_dialog_viewed', 1);

View File

@ -11,7 +11,7 @@ msgstr ""
"Project-Id-Version: Airtime\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-04 11:17-0400\n"
"PO-Revision-Date: 2015-09-11 14:33+0000\n"
"PO-Revision-Date: 2015-09-25 13:52+0000\n"
"Last-Translator: Maria Ituarte <maria.ituarte@sourcefabric.org>\n"
"Language-Team: Spanish (Spain) (http://www.transifex.com/sourcefabric/airtime/language/es_ES/)\n"
"MIME-Version: 1.0\n"
@ -22,7 +22,7 @@ msgstr ""
#: airtime_mvc/application/services/CalendarService.php:50
msgid "Record file doesn't exist"
msgstr ""
msgstr "No existe el archivo"
#: airtime_mvc/application/services/CalendarService.php:54
msgid "View Recorded File Metadata"
@ -1941,7 +1941,7 @@ msgstr "Stream en vivo"
#: airtime_mvc/application/layouts/scripts/layout.phtml:63
msgid "Smart Block"
msgstr ""
msgstr "Bloque Inteligente"
#: airtime_mvc/application/layouts/scripts/layout.phtml:66
msgid "Webstream"

View File

@ -11,8 +11,8 @@ msgstr ""
"Project-Id-Version: Airtime\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-09-04 11:17-0400\n"
"PO-Revision-Date: 2015-09-05 08:33+0000\n"
"Last-Translator: Daniel James <daniel@64studio.com>\n"
"PO-Revision-Date: 2015-09-28 12:25+0000\n"
"Last-Translator: dave van den berg <d.berg501@gmail.com>\n"
"Language-Team: Dutch (Netherlands) (http://www.transifex.com/sourcefabric/airtime/language/nl_NL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -22,7 +22,7 @@ msgstr ""
#: airtime_mvc/application/services/CalendarService.php:50
msgid "Record file doesn't exist"
msgstr "ecord bestand bestaat niet"
msgstr "Record bestand bestaat niet"
#: airtime_mvc/application/services/CalendarService.php:54
msgid "View Recorded File Metadata"
@ -31,25 +31,25 @@ msgstr "Weergave opgenomen bestand Metadata"
#: airtime_mvc/application/services/CalendarService.php:61
#: airtime_mvc/application/services/CalendarService.php:93
msgid "View"
msgstr ""
msgstr "Weergeven"
#: airtime_mvc/application/services/CalendarService.php:81
msgid "Schedule Tracks"
msgstr ""
msgstr "Schema Tracks"
#: airtime_mvc/application/services/CalendarService.php:106
msgid "Clear Show"
msgstr ""
msgstr "Wissen show"
#: airtime_mvc/application/services/CalendarService.php:120
#: airtime_mvc/application/services/CalendarService.php:125
msgid "Cancel Show"
msgstr ""
msgstr "Annuleren show"
#: airtime_mvc/application/services/CalendarService.php:146
#: airtime_mvc/application/services/CalendarService.php:165
msgid "Edit Instance"
msgstr ""
msgstr "Aanleg bewerken"
#: airtime_mvc/application/services/CalendarService.php:152
#: airtime_mvc/application/controllers/LibraryController.php:184
@ -74,11 +74,11 @@ msgstr "Verwijderen"
#: airtime_mvc/application/services/CalendarService.php:194
msgid "Delete Instance"
msgstr ""
msgstr "Exemplaar verwijderen"
#: airtime_mvc/application/services/CalendarService.php:200
msgid "Delete Instance and All Following"
msgstr ""
msgstr "Exemplaar verwijderen en alle volgende"
#: airtime_mvc/application/services/CalendarService.php:254
msgid "Permission denied"
@ -275,16 +275,16 @@ msgstr "Download"
#: airtime_mvc/application/controllers/LibraryController.php:147
msgid "View track"
msgstr ""
msgstr "Weergave track"
#: airtime_mvc/application/controllers/LibraryController.php:148
msgid "Remove track"
msgstr ""
msgstr "Nummer verwijderen"
#: airtime_mvc/application/controllers/LibraryController.php:154
#: airtime_mvc/application/controllers/LibraryController.php:159
msgid "Upload track"
msgstr ""
msgstr "Uploaden van track"
#: airtime_mvc/application/controllers/LibraryController.php:169
msgid "Duplicate Playlist"
@ -300,11 +300,11 @@ msgstr "Je hebt geen toestemming om geselecteerde items te verwijderen"
#: airtime_mvc/application/controllers/LibraryController.php:279
msgid "Could not delete file because it is scheduled in the future."
msgstr ""
msgstr "Kan bestand niet verwijderen omdat het in de toekomst is gepland."
#: airtime_mvc/application/controllers/LibraryController.php:282
msgid "Could not delete file(s)."
msgstr ""
msgstr "Bestand(en) kan geen gegevens verwijderen."
#: airtime_mvc/application/controllers/LibraryController.php:322
#, php-format
@ -329,13 +329,13 @@ msgid ""
"To configure and use the embeddable player you must:<br><br>\n"
" 1. Enable at least one MP3, AAC, or OGG stream under System -> Streams<br>\n"
" 2. Enable the Public Airtime API under System -> Preferences"
msgstr ""
msgstr " Configureren en de integreerbare speler u moet gebruiken:<br><br>1. Inschakelen ten minste één MP3, AAC en OGG stream onder systeem->Streams<br>\n2. De openbare Airtime API inschakelen onder systeem->voorkeuren"
#: airtime_mvc/application/controllers/EmbeddablewidgetsController.php:41
msgid ""
"To use the embeddable weekly schedule widget you must:<br><br>\n"
" Enable the Public Airtime API under System -> Preferences"
msgstr ""
msgstr "De integreerbare per schema widget u moet gebruiken:<br><br>\nde openbare Airtime API inschakelen onder systeem->voorkeuren"
#: airtime_mvc/application/controllers/ListenerstatController.php:51
msgid ""
@ -391,19 +391,19 @@ msgstr "Onbekende afspeellijst"
#: airtime_mvc/application/controllers/ErrorController.php:78
msgid "Page not found."
msgstr ""
msgstr "Pagina niet gevonden"
#: airtime_mvc/application/controllers/ErrorController.php:87
msgid "The requested action is not supported."
msgstr ""
msgstr "De gevraagde actie wordt niet ondersteund."
#: airtime_mvc/application/controllers/ErrorController.php:98
msgid "You do not have permission to access this resource."
msgstr ""
msgstr "U bent niet gemachtigd voor toegang tot deze bron."
#: airtime_mvc/application/controllers/ErrorController.php:109
msgid "An internal application error has occurred."
msgstr ""
msgstr "Een interne toepassingsfout opgetreden."
#: airtime_mvc/application/controllers/Apiv2Controller.php:77
#: airtime_mvc/application/controllers/ApiController.php:79
@ -436,7 +436,7 @@ msgstr "Probleem met Liquidsoap..."
#: airtime_mvc/application/controllers/PreferenceController.php:493
msgid "Request method not accepted"
msgstr ""
msgstr "Verzoek methode niet geaccepteerd"
#: airtime_mvc/application/controllers/DashboardController.php:35
#: airtime_mvc/application/controllers/DashboardController.php:84
@ -454,7 +454,7 @@ msgstr "Je hebt geen toestemming om over te schakelen van de bron."
#: airtime_mvc/application/controllers/LoginController.php:43
msgid "Please enter your username and password."
msgstr ""
msgstr "Voer uw gebruikersnaam en wachtwoord."
#: airtime_mvc/application/controllers/LoginController.php:93
msgid "Wrong username or password provided. Please try again."
@ -468,7 +468,7 @@ msgstr "E-mail kan niet worden verzonden. Controleer de instellingen van uw e-ma
#: airtime_mvc/application/controllers/LoginController.php:173
msgid "There was a problem with the username or email address you entered."
msgstr ""
msgstr "Er was een probleem met de gebruikersnaam of email adres dat u hebt ingevoerd."
#: airtime_mvc/application/controllers/ApiController.php:244
#: airtime_mvc/application/controllers/ApiController.php:317
@ -570,39 +570,39 @@ msgstr "Selecteer een cursorpositie op de tijdlijn."
#: airtime_mvc/application/controllers/LocaleController.php:54
msgid "You haven't added any tracks"
msgstr ""
msgstr "U hebt de nummers nog niet toegevoegd"
#: airtime_mvc/application/controllers/LocaleController.php:55
msgid "You haven't added any playlists"
msgstr ""
msgstr "U heb niet alle afspeellijsten toegevoegd"
#: airtime_mvc/application/controllers/LocaleController.php:56
msgid "You haven't added any smart blocks"
msgstr ""
msgstr "U nog niet toegevoegd een slimme blokken"
#: airtime_mvc/application/controllers/LocaleController.php:57
msgid "You haven't added any webstreams"
msgstr ""
msgstr "U hebt webstreams nog niet toegevoegd"
#: airtime_mvc/application/controllers/LocaleController.php:58
msgid "Learn about tracks"
msgstr ""
msgstr "Informatie over nummers"
#: airtime_mvc/application/controllers/LocaleController.php:59
msgid "Learn about playlists"
msgstr ""
msgstr "Meer informatie over afspeellijsten"
#: airtime_mvc/application/controllers/LocaleController.php:60
msgid "Learn about smart blocks"
msgstr ""
msgstr "Informatie over slimme blokken"
#: airtime_mvc/application/controllers/LocaleController.php:61
msgid "Learn about webstreams"
msgstr ""
msgstr "Meer informatie over webstreams"
#: airtime_mvc/application/controllers/LocaleController.php:62
msgid "Click 'New' to create one."
msgstr ""
msgstr "Klik op 'Nieuw' te maken."
#: airtime_mvc/application/controllers/LocaleController.php:67
msgid "Add to selected show"
@ -636,12 +636,12 @@ msgstr "Gepland"
#: airtime_mvc/application/layouts/scripts/layout.phtml:78
#: airtime_mvc/application/views/scripts/showbuilder/builderDialog.phtml:7
msgid "Tracks"
msgstr ""
msgstr "track"
#: airtime_mvc/application/controllers/LocaleController.php:75
#: airtime_mvc/application/layouts/scripts/layout.phtml:60
msgid "Playlist"
msgstr ""
msgstr "Afspeellijsten"
#: airtime_mvc/application/controllers/LocaleController.php:79
msgid "Bit Rate"
@ -1068,7 +1068,7 @@ msgstr "Als je live streaming client niet om een gebruikersnaam vraagt, moet dit
msgid ""
"WARNING: This will restart your stream and may cause a short dropout for "
"your listeners!"
msgstr ""
msgstr "Waarschuwing: Dit zal opnieuw opstarten van uw stream en een korte dropout kan veroorzaken voor uw luisteraars!"
#: airtime_mvc/application/controllers/LocaleController.php:185
msgid ""
@ -1255,19 +1255,19 @@ msgstr "dec"
#: airtime_mvc/application/controllers/LocaleController.php:245
msgid "Today"
msgstr ""
msgstr "vandaag"
#: airtime_mvc/application/controllers/LocaleController.php:246
msgid "Day"
msgstr ""
msgstr "dag"
#: airtime_mvc/application/controllers/LocaleController.php:247
msgid "Week"
msgstr ""
msgstr "week"
#: airtime_mvc/application/controllers/LocaleController.php:248
msgid "Month"
msgstr ""
msgstr "maand"
#: airtime_mvc/application/controllers/LocaleController.php:249
#: airtime_mvc/application/forms/GeneralPreferences.php:158
@ -1384,15 +1384,15 @@ msgstr "Duur"
#: airtime_mvc/application/controllers/LocaleController.php:276
msgid "Filtering out "
msgstr ""
msgstr "Filteren op"
#: airtime_mvc/application/controllers/LocaleController.php:277
msgid " of "
msgstr ""
msgstr "of"
#: airtime_mvc/application/controllers/LocaleController.php:278
msgid " records"
msgstr ""
msgstr "records"
#: airtime_mvc/application/controllers/LocaleController.php:284
#: airtime_mvc/application/layouts/scripts/layout.phtml:140
@ -1492,7 +1492,7 @@ msgstr "Niets selecteren"
#: airtime_mvc/application/controllers/LocaleController.php:306
msgid "Trim overbooked shows"
msgstr ""
msgstr "Trim overboekte shows"
#: airtime_mvc/application/controllers/LocaleController.php:307
msgid "Remove selected scheduled items"
@ -1840,11 +1840,11 @@ msgstr "%sPrint weergave%sA.u.b. gebruik printfunctie in uw browser wilt afdrukk
#: airtime_mvc/application/controllers/LocaleController.php:407
msgid "New Show"
msgstr ""
msgstr "Nieuw Show"
#: airtime_mvc/application/controllers/LocaleController.php:408
msgid "New Log Entry"
msgstr ""
msgstr "Nieuwe logboekvermelding"
#: airtime_mvc/application/controllers/ShowbuilderController.php:138
msgid "Select cursor"
@ -1865,43 +1865,43 @@ msgstr "Rebroadcast van show %s van %s in %s"
#: airtime_mvc/application/common/UsabilityHints.php:55
msgid "Upload some tracks below to add them to your library!"
msgstr ""
msgstr "Uploaden sommige tracks hieronder toe te voegen aan uw bibliotheek!"
#: airtime_mvc/application/common/UsabilityHints.php:57
#, php-format
msgid ""
"It looks like you haven't uploaded any audio files yet. %sUpload a file "
"now%s."
msgstr ""
msgstr "Het lijkt erop dat u alle audio bestanden nog niet hebt geüpload. %sUpload een bestand nu%s."
#: airtime_mvc/application/common/UsabilityHints.php:63
msgid "Click the 'New Show' button and fill out the required fields."
msgstr ""
msgstr "Klik op de knop 'Nieuwe Show' en vul de vereiste velden."
#: airtime_mvc/application/common/UsabilityHints.php:65
#, php-format
msgid ""
"It looks like you don't have any shows scheduled. %sCreate a show now%s."
msgstr ""
msgstr "Het lijkt erop dat u niet alle shows gepland. %sCreate een show nu%s."
#: airtime_mvc/application/common/UsabilityHints.php:73
msgid ""
"To start broadcasting, cancel the current linked show by clicking on it and "
"selecting 'Cancel Show'."
msgstr ""
msgstr "Om te beginnen omroep, de huidige gekoppelde show te annuleren door op te klikken en te selecteren 'Annuleren Show'."
#: airtime_mvc/application/common/UsabilityHints.php:75
#, php-format
msgid ""
"Linked shows need to be filled with tracks before it starts. To start broadcasting cancel the current linked show and schedule an unlinked show.\n"
" %sCreate an unlinked show now%s."
msgstr ""
msgstr "Gekoppelde toont dienen te worden opgevuld met tracks voordat het begint. Om te beginnen met omroep annuleren de huidige gekoppeld Toon en plannen van een niet-gekoppelde show.\n%sCreate een niet-gekoppelde Toon nu%s."
#: airtime_mvc/application/common/UsabilityHints.php:80
msgid ""
"To start broadcasting, click on the current show and select 'Schedule "
"Tracks'"
msgstr ""
msgstr "Om te beginnen omroep, klik op de huidige show en selecteer 'Schema Tracks'"
#: airtime_mvc/application/common/UsabilityHints.php:82
#, php-format

View File

@ -113,11 +113,33 @@ label.wrapp-label input[type="checkbox"] {
display: none;
}
#add_show_hosts-label {
width: 100%;
padding-bottom: 10px;
}
#add_show_hosts-element {
max-height: 80px;
min-width: 150px;
}
#add_show_hosts-element > label {
display: flex;
align-items: flex-end;
}
#add_show_hosts-element input {
margin-right: 6px;
}
#schedule-show-who {
overflow-x: hidden;
}
#add_show_logo {
margin-top: 6px;
}
#add_show_start_time, #add_show_end_time {
width: 54px;
margin-left: 10px;

View File

@ -42,13 +42,6 @@
}
}
@media screen and (max-width: 1265px) {
.dataTables_length > label {
/* Hacky, but datatables dumps the select inside the label for some reason... */
font-size: 0 !important;
}
}
@media screen and (max-width: 1200px) {
.wrapper {
-webkit-flex-flow: column !important;
@ -339,6 +332,9 @@ thead th.ui-state-default:focus {
.sb-options-form label {
color: #efefef;
line-height: 26px;
display: inline-block;
padding: 0 0 0 4px;
vertical-align: middle;
}
#sb_show_filter {
@ -346,6 +342,11 @@ thead th.ui-state-default:focus {
position: absolute;
}
#sb_my_shows {
top: 1px;
left: 2px;
}
.nav-tabs {
border-bottom: 1px solid #5b5b5b;
font-family: Arial, Helvetica, sans-serif;
@ -536,10 +537,10 @@ li.ui-state-default {
}
.spl_sortable {
position: relative;
height: 100%;
overflow: auto;
flex: 1 100%;
-webkit-flex: 1 100%;
margin: 4px 0;
min-height: 0;

View File

@ -605,9 +605,9 @@ table.fc-border-separate {
left: 0;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.3;
filter: alpha(opacity=30);
background: #C3C3C3;
opacity: 0.15;
filter: alpha(opacity=15);
}
.fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */

View File

@ -950,7 +950,7 @@ dl.inline-list dd {
background: url("img/loading.gif") no-repeat 50% 50% rgba(0, 0, 0, .25);
}
div.blockOverlay {
background: url("img/loading.gif") no-repeat 50% 50% rgba(0, 0, 0, .45);
background: 50% 50% rgba(0, 0, 0, .45);
}
#library_display_wrapper .ui-widget-header:first-child {
background:none;
@ -981,7 +981,7 @@ div.blockOverlay {
font-size:12px;
font-weight:normal;
padding: 0.2em 1em;
margin-right:3px;
margin-right:0;
}
.dataTables_filter input {
background: url("images/search_auto_bg.png") no-repeat scroll 0 0 #DDDDDD;
@ -1371,7 +1371,7 @@ thead tr.fc-first
height: 32px;
line-height: 32px;
}
ful
/** Extremely nasty workaround for a fullcalendar bug, where clicking "Add Show"
would cause this large space under the table header. The CSS to get to that
is ridiculously complicated and set in the HTML (!) dynamically with JS,
@ -3540,7 +3540,7 @@ button.btn-icon-text > i.icon-white {
}
#media_selector_wrapper {
flex: 0 0 100%;
flex: 1 1 100%;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
@ -3869,13 +3869,15 @@ li .ui-state-hover {
-webkit-flex-flow: column;
flex-flow: column;
flex: 6 auto;
flex: 1 1;
-webkit-flex: 1 1;
min-width: 505px;
}
.outer-datatable-wrapper {
position: relative;
flex: 1;
-webkit-flex: 1;
}
#user_list_inner_wrapper {
@ -3942,4 +3944,49 @@ li .ui-state-hover {
.podcast-metadata input[type="text"] {
width: 60%;
}
}
/* UI Revamp Video */
#whatsnew {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
max-width: 640px;
max-height: 470px;
padding: 10px 10px;
}
#whatsnew_video {
text-align: center;
}
#whatsnew > button {
margin-top: 10px;
align-self: flex-end;
flex: 1 0 auto;
}
#whatsnew > div {
text-align: left;
font-size: 16px;
overflow-x: hidden;
padding: 20px;
box-sizing: border-box;
}
#whatsnew iframe {
text-align: center;
}
#whatsnew h2 {
margin-top: 10px;
font-weight: bold;
text-align: center;
}
#whatsnew li {
margin-top: 20px;
}

View File

@ -88,13 +88,19 @@ function getDatatablesStrings(overrideDict) {
"sSearch": $.i18n._(""),
"sZeroRecords": $.i18n._("No matching records found"),
"oPaginate": {
"sFirst": $.i18n._("First"),
"sLast": $.i18n._("Last"),
"sNext": $.i18n._("Next"),
"sPrevious": $.i18n._("Previous")
"sFirst": "&laquo;",
"sLast": "&raquo;",
"sNext": "&rsaquo;",
"sPrevious": "&lsaquo;"
},
//"oPaginate": {
// "sFirst": $.i18n._("First"),
// "sLast": $.i18n._("Last"),
// "sNext": $.i18n._("Next"),
// "sPrevious": $.i18n._("Previous")
//},
"oAria": {
"sSortAscending": $.i18n._(": activate to sort column ascending"),
"sSortAscending": $.i18n._(": activate to sort column ascending"),
"sSortDescending": $.i18n._(": activate to sort column descending")
}
};
@ -317,4 +323,4 @@ jQuery.fn.textScroll = function(selector) {
});
return this; // jQuery chaining
};
};

View File

@ -18,6 +18,7 @@ var AIRTIME = (function(AIRTIME) {
check = true;
}
var sortable = $(".spl_sortable");
if ($("#show_builder_table").is(":visible")) {
if (shows.length === 0) {
check = false;
@ -28,13 +29,15 @@ var AIRTIME = (function(AIRTIME) {
} else if (current.length !== 0) {
btnText = $.i18n._('Add to current show');
}
} else {
} else if (sortable.length > 0 && sortable.is(":visible")) {
var objType = $('.active-tab .obj_type').val();
if (objType === 'block') {
btnText = $.i18n._('Add to current smart block');
} else {
btnText = $.i18n._('Add to current playlist');
}
} else {
check = false;
}
if (check) {
@ -100,86 +103,95 @@ var AIRTIME = (function(AIRTIME) {
libEmpty.hide();
}
var sortable;
if ($("#show_builder_table").is(":visible")) {
$('#library_display tr[class*="lib-"]')
.draggable(
{
helper: function () {
var $el = $(this), selected = mod
.getChosenItemsLength(), container, thead = $("#show_builder_table thead"), colspan = thead
.find("th").length, width = $el.width(), message;
// dragging an element that has an unselected
// checkbox.
if (mod.isChosenItem($el) === false) {
selected++;
}
if (selected === 1) {
message = $.i18n._("Adding 1 Item");
} else {
message = sprintf($.i18n._("Adding %s Items"), selected);
}
container = $('<div/>').attr('id',
'draggingContainer').append('<tr/>')
.find("tr").append('<td/>').find("td")
.attr("colspan", colspan).width(width)
.addClass("ui-state-highlight").append(
message).end().end();
return container;
},
cursor: 'move',
//cursorAt: {
// top: 30,
// right: 10
//},
distance: 25, // min-distance for dragging
connectToSortable: '#show_builder_table'
});
sortable = "#show_builder_table";
} else {
$('#library_display tr[class*="lib-"]')
.draggable(
{
helper: function () {
var $el = $(this), selected = mod
.getChosenAudioFilesLength(), container, message,
width = $(this).width(), height = 55;
// dragging an element that has an unselected
// checkbox.
if (mod.isChosenItem($el) === false) {
selected++;
}
if (selected === 1) {
message = $.i18n._("Adding 1 Item");
} else {
message = sprintf($.i18n._("Adding %s Items"), selected);
}
container = $('<div class="helper"/>').append(
"<li/>").find("li").addClass(
"ui-state-default").append("<div/>")
.find("div").addClass(
"list-item-container").append(
message).end().width(width)
.height(height).end();
return container;
},
cursor: 'move',
//cursorAt: {
// top: 30,
// right: 10
//},
distance: 25, // min-distance for dragging
connectToSortable: '.active-tab .spl_sortable'
});
sortable = ".active-tab .spl_sortable";
//$('#library_display tr[class*="lib-"]')
// .draggable(
// {
// helper: function () {
//
// var $el = $(this), selected = mod
// .getChosenAudioFilesLength(), container, message,
// width = $(this).width(), height = 55;
//
// // dragging an element that has an unselected
// // checkbox.
// if (mod.isChosenItem($el) === false) {
// selected++;
// }
//
// if (selected === 1) {
// message = $.i18n._("Adding 1 Item");
// } else {
// message = sprintf($.i18n._("Adding %s Items"), selected);
// }
//
// container = $('<div class="helper"/>').append(
// "<li/>").find("li").addClass(
// "ui-state-default").append("<div/>")
// .find("div").addClass(
// "list-item-container").append(
// message).end().width(width)
// .height(height).end();
//
// return container;
// },
// create: function(event, ui) {
// $(this).draggable("option", "cursorAt", {
// left: Math.floor(this.clientWidth / 2)
// });
// },
// cursor: 'move',
// distance: 25, // min-distance for dragging
// connectToSortable: '.active-tab .spl_sortable'
// });
}
$('#library_display tr[class*="lib-"]')
.draggable(
{
helper: function () {
var $el = $(this), selected = mod
.getChosenItemsLength(), container, thead = $("#show_builder_table thead"), colspan = thead
.find("th").length, width = $el.width(), message;
// dragging an element that has an unselected
// checkbox.
if (mod.isChosenItem($el) === false) {
selected++;
}
if (selected === 1) {
message = $.i18n._("Adding 1 Item");
} else {
message = sprintf($.i18n._("Adding %s Items"), selected);
}
container = $('<div/>').attr('id',
'draggingContainer').append('<tr/>')
.find("tr").append('<td/>').find("td")
.attr("colspan", colspan).width(width)
.addClass("ui-state-highlight").append(
message).end().end();
return container;
},
create: function(event, ui) {
$(this).draggable("option", "cursorAt", {
top: 20,
left: Math.floor($(this).outerWidth() / 2)
});
},
tolerance: 'pointer',
cursor: 'move',
distance: 25, // min-distance for dragging
connectToSortable: sortable
});
};
mod.dblClickAdd = function(data, type) {

View File

@ -847,12 +847,6 @@ var AIRTIME = (function(AIRTIME) {
return getDatatablesStrings({
"sEmptyTable": $.i18n._(""),
"sZeroRecords": $.i18n._("No matching results found.")
//"oPaginate": {
// "sFirst": "<<",
// "sLast": ">>",
// "sNext": ">",
// "sPrevious": "<"
//}
});
break;
}

View File

@ -20,6 +20,7 @@ $(document).ready(function () {
acceptedFiles: acceptedMimeTypes.join(),
addRemoveLinks: true,
dictRemoveFile: $.i18n._("Remove"),
maxFilesize: 500, //Megabytes
init: function () {
this.on("sending", function (file, xhr, data) {
data.append("csrf_token", $("#csrf").val());

View File

@ -18,6 +18,7 @@ var AIRTIME = (function (AIRTIME) {
//when you're creating a new podcast, we already have the object from the result of the POST. We're saving
//a roundtrip by not fetching it again here.
$scope.podcast = podcast;
console.log(podcast);
tab.setName($scope.podcast.title);
$scope.savePodcast = function() {
@ -25,7 +26,6 @@ var AIRTIME = (function (AIRTIME) {
podcastData.episodes = episodeTable.getSelectedRows();
$http.put(endpoint + $scope.podcast.id, { csrf_token: jQuery("#csrf").val(), podcast: podcastData })
.success(function() {
// TODO refresh the table here somehow..
episodeTable.reload($scope.podcast.id);
});
};
@ -39,12 +39,16 @@ var AIRTIME = (function (AIRTIME) {
function _bulkAction(method, callback) {
var ids = [], selectedData = AIRTIME.library.podcastTableWidget.getSelectedRows();
selectedData.forEach(function(el) {
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+el.id;
var t = AIRTIME.tabs.get(uid);
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+el.id,
t = AIRTIME.tabs.get(uid);
if (t && method == HTTPMethods.DELETE) {
t.close();
}
if (!(t && method == HTTPMethods.GET)) ids.push(el.id);
if (!(t && method == HTTPMethods.GET)) {
ids.push(el.id);
} else if (t != AIRTIME.tabs.getActiveTab()) {
t.switchTo();
}
});
if (ids.length > 0) {
@ -62,6 +66,14 @@ var AIRTIME = (function (AIRTIME) {
angular.bootstrap(wrapper.get(0), ["podcast"]);
}
function _initAppFromResponse(data) {
var podcast = JSON.parse(data.podcast),
uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
tab = AIRTIME.tabs.openTab(data, uid, null),
table = mod.initPodcastEpisodeDatatable(podcast.episodes);
_bootstrapAngularApp(podcast, tab, table);
}
mod.createUrlDialog = function() {
$.get('/render/podcast-url-dialog', function(json) {
$(document.body).append(json.html);
@ -77,11 +89,7 @@ var AIRTIME = (function (AIRTIME) {
mod.addPodcast = function() {
$.post(endpoint, $("#podcast_url_dialog").find("form").serialize(), function(json) {
var podcast = JSON.parse(json.podcast);
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
tab = AIRTIME.tabs.openTab(json, uid, null);
var table = mod.initPodcastEpisodeDatatable(podcast.episodes);
_bootstrapAngularApp(podcast, tab, table);
_initAppFromResponse(json);
$("#podcast_url_dialog").dialog("close");
});
};
@ -89,11 +97,7 @@ var AIRTIME = (function (AIRTIME) {
mod.editSelectedPodcasts = function() {
_bulkAction(HTTPMethods.GET, function(json) {
json.forEach(function(data) {
var podcast = JSON.parse(data.podcast);
var uid = AIRTIME.library.MediaTypeStringEnum.PODCAST+"_"+podcast.id,
tab = AIRTIME.tabs.openTab(data, uid, null);
var table = mod.initPodcastEpisodeDatatable(podcast.episodes);
_bootstrapAngularApp(podcast, tab, table);
_initAppFromResponse(data);
});
});
};
@ -140,7 +144,6 @@ var AIRTIME = (function (AIRTIME) {
});
};
// This method is static, so use AIRTIME.widgets.Table
var podcastToolbarButtons = AIRTIME.widgets.Table.getStandardToolbarButtons();
// Set up the div with id "podcast_table" as a datatable.

View File

@ -224,7 +224,7 @@ function buildScheduleDialog (json, instance_id) {
}
]
});
//set the start end times so the builder datatables knows its time range.
fnServer.start = json.start;
fnServer.end = json.end;

View File

@ -766,7 +766,7 @@ var AIRTIME = (function(AIRTIME){
"bScrollCollapseY": false
});
$sbTable.find("tbody").on("mousedown", "tr:not(.sb-header, .sb-footer, .sb-past, .sb-empty, :has(td.dataTables_empty)) > td.sb-checkbox", function(ev) {
$sbTable.find("tbody").on("mousedown", "tr:not(.sb-not-allowed, .sb-header, .sb-footer, .sb-past, .sb-empty, :has(td.dataTables_empty)) > td.sb-checkbox", function(ev) {
var $tr = $(this).parent(),
// Get the ID of the selected row
$rowId = $tr.attr("id");
@ -803,7 +803,7 @@ var AIRTIME = (function(AIRTIME){
$previouslySelected = $tr;
});
$sbTable.find("tbody").on("mousedown", "tr:not(.sb-header, .sb-footer, .sb-past, .sb-empty, :has(td.dataTables_empty)) > td:not(.sb-checkbox)", function(ev) {
$sbTable.find("tbody").on("mousedown", "tr:not(.sb-not-allowed, .sb-header, .sb-footer, .sb-past, .sb-empty, :has(td.dataTables_empty)) > td:not(.sb-checkbox)", function(ev) {
var $tr = $(this).parent(),
// Get the ID of the selected row
$rowId = $tr.attr("id");
@ -851,7 +851,7 @@ var AIRTIME = (function(AIRTIME){
$previouslySelected = $tr;
});
$sbTable.find("tbody").on("click", "tr:not(.sb-header, .sb-footer, .sb-past, .sb-empty, :has(td.dataTables_empty)) > td.sb-checkbox", function() {
$sbTable.find("tbody").on("click", "tr:not(.sb-not-allowed, .sb-header, .sb-footer, .sb-past, .sb-empty, :has(td.dataTables_empty)) > td.sb-checkbox", function() {
var tr = $(this).parent();
if (flagForDeselection) {
flagForDeselection = false;
@ -867,7 +867,7 @@ var AIRTIME = (function(AIRTIME){
selectedRows = $("." + SB_SELECTED_CLASS);
});
$sbTable.find("tbody").on("click", "tr:not(.sb-header, .sb-footer, .sb-past, .sb-empty, :has(td.dataTables_empty)) > td:not(.sb-checkbox)", function(e) {
$sbTable.find("tbody").on("click", "tr:not(.sb-not-allowed, .sb-header, .sb-footer, .sb-past, .sb-empty, :has(td.dataTables_empty)) > td:not(.sb-checkbox)", function(e) {
var tr = $(this).parent();
if (flagForDeselection) {
flagForDeselection = false;
@ -887,7 +887,7 @@ var AIRTIME = (function(AIRTIME){
//begin context menu initialization.
$.contextMenu({
selector: '#show_builder tr.lib-audio:not(.sb-past)',
selector: '#show_builder tr.lib-audio:not(.sb-not-allowed, .sb-past)',
trigger: "right",
build: function($el, e) {

View File

@ -93,7 +93,7 @@ AIRTIME = (function(AIRTIME) {
check;
check = validateTimeRange();
if (check.isValid) {
//reset timestamp value since input values could have changed.
AIRTIME.showbuilder.resetTimestamp();
@ -102,14 +102,15 @@ AIRTIME = (function(AIRTIME) {
fn.start = check.start;
fn.end = check.end;
op = $("div.sb-advanced-options");
op = $("div.sb-options-form");
if (op.is(":visible")) {
if (fn.ops === undefined) {
fn.ops = {};
}
fn.ops.showFilter = op.find("#sb_show_filter").val();
fn.ops.myShows = op.find("#sb_my_shows").is(":checked") ? 1 : 0;
// Hacky?
fn.ops.myShows = (fn.ops.showFilter == -1) ? 1 : 0;
}
oTable.fnDraw();