Fix various calendar regressions
This commit is contained in:
parent
6cd46fedcf
commit
11ff8f71ea
8 changed files with 143 additions and 94 deletions
|
@ -1898,9 +1898,6 @@ class calendar extends rcube_plugin
|
|||
unset($event['allday']);
|
||||
|
||||
$event['className'] = $event['className'] ? explode(' ', $event['className']) : array();
|
||||
if ($addcss) {
|
||||
$event['className'][] = 'fc-event-cal-' . asciiwords($event['calendar'], true);
|
||||
}
|
||||
|
||||
if ($event['allDay']) {
|
||||
$event['end'] = $event['end']->add(new DateInterval('P1D'));
|
||||
|
|
|
@ -162,6 +162,7 @@ function rcube_calendar_ui(settings)
|
|||
element.addClass('cal-event-status-' + String(event.status).toLowerCase());
|
||||
}
|
||||
|
||||
set_event_colors(element, event, view.name);
|
||||
element.attr('aria-label', event.title + ', ' + me.event_date_text(event, true));
|
||||
},
|
||||
// callback when a specific event is clicked
|
||||
|
@ -283,6 +284,50 @@ function rcube_calendar_ui(settings)
|
|||
return date.getHours() >= settings['work_start'] && date.getHours() < settings['work_end'];
|
||||
};
|
||||
|
||||
var set_event_colors = function(element, event, mode)
|
||||
{
|
||||
var bg_color = '', border_color = '',
|
||||
cat = String(event.categories),
|
||||
color = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar].color : '',
|
||||
cat_color = rcmail.env.calendar_categories[cat] ? rcmail.env.calendar_categories[cat] : color;
|
||||
|
||||
switch (settings.event_coloring) {
|
||||
case 1:
|
||||
bg_color = border_color = cat_color;
|
||||
break;
|
||||
case 2:
|
||||
border_color = color;
|
||||
bg_color = cat_color;
|
||||
break;
|
||||
case 3:
|
||||
border_color = cat_color;
|
||||
bg_color = color;
|
||||
break;
|
||||
default:
|
||||
bg_color = border_color = color;
|
||||
break;
|
||||
}
|
||||
|
||||
var css = {
|
||||
'border-color': border_color,
|
||||
'background-color': bg_color,
|
||||
'color': me.text_color(bg_color)
|
||||
};
|
||||
|
||||
if (String(css['border-color']).match(/^#?f+$/i))
|
||||
delete css['border-color'];
|
||||
|
||||
$.each(css, function(i, v) { if (!v) delete css[i]; if (v.charAt(0) != '#') css[i] = '#' + v; });
|
||||
|
||||
if (mode == 'list') {
|
||||
bg_color = css['background-color'];
|
||||
if (bg_color && !bg_color.match(/^#?f+$/i))
|
||||
$(element).find('.fc-event-dot').css('background-color', bg_color);
|
||||
}
|
||||
else
|
||||
$(element).css(css);
|
||||
};
|
||||
|
||||
var load_attachment = function(data)
|
||||
{
|
||||
var event = data.record,
|
||||
|
@ -340,24 +385,17 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
$dialog.find('div.event-section, div.event-line, .form-group').hide();
|
||||
$('#event-title').html(Q(event.title)).show();
|
||||
|
||||
|
||||
if (event.location)
|
||||
$('#event-location').html('@ ' + text2html(event.location)).show();
|
||||
if (event.description)
|
||||
$('#event-description').show().find('.event-text').html(text2html(event.description, 300, 6));
|
||||
if (event.vurl)
|
||||
$('#event-url').show().find('.event-text').html(render_link(event.vurl));
|
||||
|
||||
// render from-to in a nice human-readable way
|
||||
// -> now shown in dialog title
|
||||
// $('#event-date').html(Q(me.event_date_text(event))).show();
|
||||
|
||||
if (event.recurrence && event.recurrence_text)
|
||||
$('#event-repeat').show().find('.event-text').html(Q(event.recurrence_text));
|
||||
|
||||
if (event.valarms && event.alarms_text)
|
||||
$('#event-alarm').show().find('.event-text').html(Q(event.alarms_text).replace(',', ',<br>'));
|
||||
|
||||
if (calendar.name)
|
||||
$('#event-calendar').show().find('.event-text').text(calendar.name).addClass('cal-'+calendar.id);
|
||||
if (event.categories)
|
||||
|
@ -2496,7 +2534,7 @@ function rcube_calendar_ui(settings)
|
|||
|
||||
event.editable = false;
|
||||
event.temp = true;
|
||||
event.className = ['fc-event-cal-'+data.calendar, 'fc-event-temp'];
|
||||
event.className = ['fc-event-temp'];
|
||||
|
||||
fc.fullCalendar(data.id ? 'updateEvent' : 'renderEvent', event);
|
||||
|
||||
|
@ -3408,28 +3446,13 @@ function rcube_calendar_ui(settings)
|
|||
// register the given calendar to the current view
|
||||
var add_calendar_source = function(cal)
|
||||
{
|
||||
var color, brightness, select, id = cal.id;
|
||||
var brightness, select, id = cal.id;
|
||||
|
||||
me.calendars[id] = $.extend({
|
||||
url: rcmail.url('calendar/load_events', { source: id }),
|
||||
className: ['fc-event-cal-' + id],
|
||||
id: id
|
||||
}, cal);
|
||||
|
||||
// choose black text color when background is bright, white otherwise
|
||||
if (color = settings.event_coloring % 2 ? '' : '#' + cal.color) {
|
||||
me.calendars[id].color = color;
|
||||
me.calendars[id].textColor = 'white';
|
||||
|
||||
if (/^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i.test(color)) {
|
||||
// use information about brightness calculation found at
|
||||
// http://javascriptrules.com/2009/08/05/css-color-brightness-contrast-using-javascript/
|
||||
brightness = (parseInt(RegExp.$1, 16) * 299 + parseInt(RegExp.$2, 16) * 587 + parseInt(RegExp.$3, 16) * 114) / 1000;
|
||||
if (brightness > 125)
|
||||
me.calendars[id].textColor = '#222';
|
||||
}
|
||||
}
|
||||
|
||||
if (fc && (cal.active || cal.subscribed)) {
|
||||
if (cal.active)
|
||||
fc.fullCalendar('addEventSource', me.calendars[id]);
|
||||
|
@ -3648,7 +3671,6 @@ function rcube_calendar_ui(settings)
|
|||
if (rcmail.env.itip_events && rcmail.env.itip_events.length) {
|
||||
me.calendars['--invitation--itip'] = {
|
||||
events: rcmail.env.itip_events,
|
||||
className: ['fc-event-cal---invitation--itip'],
|
||||
color: '#fff',
|
||||
textColor: '#333',
|
||||
editable: false,
|
||||
|
@ -3750,6 +3772,7 @@ function rcube_calendar_ui(settings)
|
|||
},
|
||||
viewRender: function(view, element) {
|
||||
$('#agendaoptions')[view.name == 'list' ? 'show' : 'hide']();
|
||||
|
||||
if (minical) {
|
||||
window.setTimeout(function(){ minical.datepicker('setDate', fc.fullCalendar('getDate').toDate()); }, exec_deferred);
|
||||
if (view.name != current_view)
|
||||
|
@ -3758,16 +3781,20 @@ function rcube_calendar_ui(settings)
|
|||
me.update_state();
|
||||
}
|
||||
|
||||
if (view.name == 'list') {
|
||||
var viewStart = moment(view.start);
|
||||
var viewStart = moment(view.start);
|
||||
|
||||
$('#calendar .fc-prev-button').off('click').on('click', function() {
|
||||
$('#calendar .fc-prev-button').off('click').on('click', function() {
|
||||
if (view.name == 'list')
|
||||
fc.fullCalendar('gotoDate', viewStart.subtract(settings.agenda_range, 'days'));
|
||||
});
|
||||
$('#calendar .fc-next-button').off('click').on('click', function() {
|
||||
else
|
||||
fc.fullCalendar('prev');
|
||||
});
|
||||
$('#calendar .fc-next-button').off('click').on('click', function() {
|
||||
if (view.name == 'list')
|
||||
fc.fullCalendar('gotoDate', viewStart.add(settings.agenda_range, 'days'));
|
||||
});
|
||||
}
|
||||
else
|
||||
fc.fullCalendar('next');
|
||||
});
|
||||
},
|
||||
eventAfterAllRender: function(view) {
|
||||
if (view.name == 'list') {
|
||||
|
|
|
@ -145,41 +145,30 @@ class calendar_ui
|
|||
*/
|
||||
function calendar_css($attrib = array())
|
||||
{
|
||||
$categories = $this->cal->driver->list_categories();
|
||||
$js_categories = array();
|
||||
$mode = $this->rc->config->get('calendar_event_coloring', $this->cal->defaults['calendar_event_coloring']);
|
||||
$categories = $this->cal->driver->list_categories();
|
||||
$css = "\n";
|
||||
|
||||
$css = "\n";
|
||||
|
||||
foreach ((array)$categories as $class => $color) {
|
||||
if (empty($color))
|
||||
continue;
|
||||
|
||||
$class = 'cat-' . asciiwords(strtolower($class), true);
|
||||
$css .= ".$class { color: #$color }\n";
|
||||
if ($mode > 0) {
|
||||
if ($mode == 2) {
|
||||
$css .= ".fc-event-$class .fc-event-bg {";
|
||||
$css .= " opacity: 0.9;";
|
||||
$css .= " filter: alpha(opacity=90);";
|
||||
}
|
||||
else {
|
||||
$css .= ".fc-event-$class.fc-event-skin, ";
|
||||
$css .= ".fc-event-$class .fc-event-skin, ";
|
||||
$css .= ".fc-event-$class .fc-event-inner {";
|
||||
}
|
||||
$css .= " background-color: #" . $color . ";";
|
||||
if ($mode % 2)
|
||||
$css .= " border-color: #$color;";
|
||||
$css .= "}\n";
|
||||
if (!empty($color)) {
|
||||
$js_categories[$class] = $color;
|
||||
|
||||
$color = ltrim($color, '#');
|
||||
$class = 'cat-' . asciiwords(strtolower($class), true);
|
||||
$css .= ".$class { color: #$color; }\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->rc->output->set_env('calendar_categories', $js_categories);
|
||||
|
||||
$calendars = $this->cal->driver->list_calendars();
|
||||
foreach ((array)$calendars as $id => $prop) {
|
||||
if (!$prop['color'])
|
||||
continue;
|
||||
$css .= $this->calendar_css_classes($id, $prop, $mode, $attrib);
|
||||
if ($prop['color']) {
|
||||
$css .= $this->calendar_css_classes($id, $prop, $mode, $attrib);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return html::tag('style', array('type' => 'text/css'), $css);
|
||||
}
|
||||
|
||||
|
@ -192,29 +181,12 @@ class calendar_ui
|
|||
|
||||
// replace white with skin-defined color
|
||||
if (!empty($attrib['folder-fallback-color']) && preg_match('/^f+$/i', $folder_color)) {
|
||||
$folder_color = $attrib['folder-fallback-color'];
|
||||
$folder_color = ltrim($attrib['folder-fallback-color'], '#');
|
||||
}
|
||||
|
||||
$class = 'cal-' . asciiwords($id, true);
|
||||
$css = str_replace('$class', $class, $attrib['folder-class']) ?: "li .$class";
|
||||
$css .= ", #eventshow .$class { color: #$folder_color; }\n";
|
||||
|
||||
if ($mode != 1) {
|
||||
if ($mode == 3) {
|
||||
$css .= ".fc-event-$class .fc-event-bg {";
|
||||
$css .= " opacity: 0.9;";
|
||||
$css .= " filter: alpha(opacity=90);";
|
||||
}
|
||||
else {
|
||||
$css .= ".fc-event-$class, ";
|
||||
$css .= ".fc-event-$class .fc-event-inner {";
|
||||
}
|
||||
if (!$prop['printmode'])
|
||||
$css .= " background-color: #$color;";
|
||||
if ($mode % 2 == 0)
|
||||
$css .= " border-color: #$color;";
|
||||
$css .= "}\n";
|
||||
}
|
||||
$css .= " { color: #$folder_color; }\n";
|
||||
|
||||
return $css . ".$class .handle { background-color: #$color; }\n";
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
|
|||
|
||||
source.color = '#' + source.color.replace(/^#/, '');
|
||||
|
||||
if (source.color == '#ffffff')
|
||||
if (source.color.match(/^#f+$/i))
|
||||
source.color = '#ccc';
|
||||
|
||||
event_sources.push(source);
|
||||
|
|
|
@ -54,10 +54,10 @@
|
|||
<div id="searchcontrols" class="search-controls"></div>
|
||||
</div>
|
||||
<div class="footer toolbar content-frame-navigation" role="toolbar" data-hidden="big">
|
||||
<a href="#" class="button prev" onclick="$('.fc-button-prev').click()"><span class="inner"><roundcube:label name="previous" /></span></a>
|
||||
<a href="#" class="button today" onclick="$('.fc-button-today').click()"><span class="inner"><roundcube:label name="today" /></span></a>
|
||||
<a href="#" class="button prev" onclick="$('.fc-prev-button').click()"><span class="inner"><roundcube:label name="previous" /></span></a>
|
||||
<a href="#" class="button today" onclick="$('.fc-today-button').click()"><span class="inner"><roundcube:label name="today" /></span></a>
|
||||
<a href="#" class="button date" onclick="window.calendar_datepicker()"><span class="inner"><roundcube:label name="date" /></span></a>
|
||||
<a href="#" class="button next" onclick="$('.fc-button-next').click()"><span class="inner"><roundcube:label name="next" /></span></a>
|
||||
<a href="#" class="button next" onclick="$('.fc-next-button').click()"><span class="inner"><roundcube:label name="next" /></span></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1828,8 +1828,7 @@ a.dropdown-link:after {
|
|||
}
|
||||
|
||||
.fc-event .fc-bg {
|
||||
opacity: 1;
|
||||
background: unset;
|
||||
opacity: .15;
|
||||
margin-top: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -1864,6 +1863,12 @@ a.dropdown-link:after {
|
|||
color: #888;
|
||||
}
|
||||
|
||||
.fc-list-table tr.fc-invitation-tentative .fc-event-dot,
|
||||
.fc-list-table tr.fc-invitation-declined .fc-event-dot,
|
||||
.fc-list-table tr.fc-invitation-needs-action .fc-event-dot {
|
||||
background-color: #aaa;
|
||||
}
|
||||
|
||||
.fc-list-table tr.fc-invitation-tentative td.fc-list-item-title,
|
||||
.fc-list-table tr.fc-invitation-declined td.fc-list-item-title,
|
||||
.fc-list-table tr.fc-invitation-needs-action td.fc-list-item-title {
|
||||
|
|
|
@ -43,6 +43,7 @@ function rcube_libcalendaring(settings)
|
|||
var me = this;
|
||||
var gmt_offset = (new Date().getTimezoneOffset() / -60) - (settings.timezone || 0) - (settings.dst || 0);
|
||||
var client_timezone = new Date().getTimezoneOffset();
|
||||
var color_map = {};
|
||||
|
||||
// general datepicker settings
|
||||
this.datepicker_settings = {
|
||||
|
@ -333,6 +334,33 @@ function rcube_libcalendaring(settings)
|
|||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds text color for specified background color
|
||||
*/
|
||||
this.text_color = function(color)
|
||||
{
|
||||
var res = '#222';
|
||||
|
||||
if (!color) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!color_map[color]) {
|
||||
color_map[color] = '#fff';
|
||||
|
||||
if (/^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i.test(color)) {
|
||||
// use information about brightness calculation found at
|
||||
// http://javascriptrules.com/2009/08/05/css-color-brightness-contrast-using-javascript/
|
||||
brightness = (parseInt(RegExp.$1, 16) * 299 + parseInt(RegExp.$2, 16) * 587 + parseInt(RegExp.$3, 16) * 114) / 1000;
|
||||
if (brightness > 125) {
|
||||
color_map[color] = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return color_map[color];
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple plaintext to HTML converter, makig URLs clickable
|
||||
*/
|
||||
|
|
|
@ -210,6 +210,7 @@ fieldset.categories .input-group {
|
|||
@color-calendar-border: @color-layout-border;
|
||||
@color-calendar-free-bg: fadeout(@color-black-shade-text, 80%);
|
||||
@color-calendar-today: fadeout(@color-warning, 80%);
|
||||
@color-event-default: #c00;
|
||||
|
||||
.fc {
|
||||
body.quickview-active & .fc-scroller {
|
||||
|
@ -262,7 +263,7 @@ fieldset.categories .input-group {
|
|||
|
||||
button {
|
||||
height: unset;
|
||||
padding: .375rem .75rem;
|
||||
padding: .3rem .75rem;
|
||||
}
|
||||
|
||||
button.prev:before {
|
||||
|
@ -297,23 +298,38 @@ fieldset.categories .input-group {
|
|||
}
|
||||
}
|
||||
|
||||
.fc-event-dot {
|
||||
background-color: @color-event-default;
|
||||
}
|
||||
|
||||
a.fc-event, a.fc-event:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fc-event {
|
||||
font-size: 1rem;
|
||||
font-size: 13px;
|
||||
background-color: @color-event-default;
|
||||
border-color: @color-event-default;
|
||||
|
||||
.fc-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fc-bg {
|
||||
opacity: .15;
|
||||
margin-top: 1.1rem;
|
||||
}
|
||||
|
||||
&.fc-invitation-needs-action {
|
||||
border: 1px dashed #5757c7 !important;
|
||||
border: 1px dashed #5757c7;
|
||||
}
|
||||
|
||||
&.fc-invitation-tentative {
|
||||
border: 1px dashed #eb8900 !important;
|
||||
border: 1px dashed #eb8900;
|
||||
}
|
||||
|
||||
&.fc-invitation-declined {
|
||||
border: 1px dashed #c00 !important;
|
||||
border: 1px dashed #c00;
|
||||
}
|
||||
|
||||
&.fc-event-ns-other.fc-invitation-declined {
|
||||
|
@ -342,6 +358,10 @@ fieldset.categories .input-group {
|
|||
tr.fc-invitation-declined,
|
||||
tr.fc-invitation-needs-action {
|
||||
color: #888;
|
||||
|
||||
.fc-event-dot {
|
||||
background-color: #888;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue