From 11ff8f71eaa7b59af817887dcc3d856baa8f8b06 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 6 Feb 2019 09:45:58 +0100 Subject: [PATCH] Fix various calendar regressions --- plugins/calendar/calendar.php | 3 - plugins/calendar/calendar_ui.js | 93 ++++++++++++------- plugins/calendar/lib/calendar_ui.php | 66 ++++--------- plugins/calendar/print.js | 2 +- .../skins/elastic/templates/calendar.html | 6 +- plugins/calendar/skins/larry/calendar.css | 9 +- plugins/libcalendaring/libcalendaring.js | 28 ++++++ .../skins/elastic/include/calendar.less | 30 +++++- 8 files changed, 143 insertions(+), 94 deletions(-) diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index afb23854..1a03fd34 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -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')); diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index bb90d7a7..e7a2fee6 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -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(',', ',
')); - 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') { diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index 7a534d5e..a24ce6b6 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -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"; } diff --git a/plugins/calendar/print.js b/plugins/calendar/print.js index 57cb05a7..fa9a3249 100644 --- a/plugins/calendar/print.js +++ b/plugins/calendar/print.js @@ -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); diff --git a/plugins/calendar/skins/elastic/templates/calendar.html b/plugins/calendar/skins/elastic/templates/calendar.html index bfea051c..0167283e 100644 --- a/plugins/calendar/skins/elastic/templates/calendar.html +++ b/plugins/calendar/skins/elastic/templates/calendar.html @@ -54,10 +54,10 @@
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css index 4df834ea..75ab4ce7 100644 --- a/plugins/calendar/skins/larry/calendar.css +++ b/plugins/calendar/skins/larry/calendar.css @@ -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 { diff --git a/plugins/libcalendaring/libcalendaring.js b/plugins/libcalendaring/libcalendaring.js index f4e9dc91..d328b19c 100644 --- a/plugins/libcalendaring/libcalendaring.js +++ b/plugins/libcalendaring/libcalendaring.js @@ -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 */ diff --git a/plugins/libkolab/skins/elastic/include/calendar.less b/plugins/libkolab/skins/elastic/include/calendar.less index 8e7695df..eec663b5 100644 --- a/plugins/libkolab/skins/elastic/include/calendar.less +++ b/plugins/libkolab/skins/elastic/include/calendar.less @@ -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; + } } }