Fix various date calculation issues after fullCalendar upgrade

- allDay flag must be boolean
- allDay event's end date must be exclusive
This commit is contained in:
Aleksander Machniak 2019-01-09 10:31:22 +01:00
parent d08e8a8a3b
commit 5718fd40e3
3 changed files with 33 additions and 39 deletions

View file

@ -2070,11 +2070,8 @@ class calendar extends rcube_plugin
// convert dates into DateTime objects in user's current timezone // convert dates into DateTime objects in user's current timezone
$event['start'] = new DateTime($event['start'], $this->timezone); $event['start'] = new DateTime($event['start'], $this->timezone);
$event['end'] = new DateTime($event['end'], $this->timezone); $event['end'] = new DateTime($event['end'], $this->timezone);
$event['allday'] = (bool) (isset($event['allDay']) ? $event['allDay'] : $event['allday']); $event['allday'] = !empty($event['allDay']);
unset($event['allDay']);
if ($event['allday']) {
}
// start/end is all we need for 'move' action (#1480) // start/end is all we need for 'move' action (#1480)
if ($action == 'move') { if ($action == 'move') {

View file

@ -793,7 +793,7 @@ function rcube_calendar_ui(settings)
calendar: event.calendar, calendar: event.calendar,
start: date2servertime(start), start: date2servertime(start),
end: date2servertime(end), end: date2servertime(end),
allday: allday.checked?1:0, allDay: allday.checked?1:0,
title: title.val(), title: title.val(),
description: description.val(), description: description.val(),
location: location.val(), location: location.val(),
@ -2474,13 +2474,20 @@ function rcube_calendar_ui(settings)
// render event temporarily into the calendar // render event temporarily into the calendar
if ((data.start && data.end) || data.id) { if ((data.start && data.end) || data.id) {
var event = data.id ? $.extend(fc.fullCalendar('clientEvents', data.id)[0], data) : data; var tmp, event = data.id ? $.extend(fc.fullCalendar('clientEvents', data.id)[0], data) : data;
if (data.start) if (data.start)
event.start = data.start; event.start = data.start;
if (data.end) if (data.end)
event.end = data.end; event.end = data.end;
if (data.allDay !== undefined) if (data.allDay !== undefined)
event.allDay = !!data.allDay; // must be boolean for fullcalendar event.allDay = !!data.allDay; // must be boolean for fullcalendar
// For fullCalendar all-day event's end date must be exclusive
if (event.allDay && data.end && (tmp = moment(data.end)) && tmp.format('Hms') !== '000') {
event.end = moment().year(tmp.year()).month(tmp.month()).date(tmp.date()).hour(0).minute(0).second(0).add(1, 'days');
}
event.editable = false; event.editable = false;
event.temp = true; event.temp = true;
event.className = ['fc-event-cal-'+data.calendar, 'fc-event-temp']; event.className = ['fc-event-cal-'+data.calendar, 'fc-event-temp'];
@ -3837,33 +3844,18 @@ function rcube_calendar_ui(settings)
}, },
// callback when an event was dragged and finally dropped // callback when an event was dragged and finally dropped
eventDrop: function(event, delta, revertFunc) { eventDrop: function(event, delta, revertFunc) {
var allday = !event.start.hasTime(); if (!event.end || event.end.diff(event.start) < 0) {
if (event.allDay)
event.end = moment(event.start).hour(13).minute(0).second(0);
else
event.end = moment(event.start).add(2, 'hours');
}
else if (event.allDay) {
event.end.subtract(1, 'days').hour(13);
}
if (!event.end || event.end.format('x') < event.start.format('x')) { if (event.allDay)
event.end = new Date(event.start.format('x') + (allday ? DAY_MS : HOUR_MS)); event.start.hour(12);
}
// moved to all-day section: set times to 12:00 - 13:00
if (allday && !event.allDay) {
event.start.hours(12);
event.start.minutes(0);
event.start.seconds(0);
event.end.hours(13);
event.end.minutes(0);
event.end.seconds(0);
}
// moved from all-day section: set times to working hours
else if (event.allDay && !allday) {
var newstart = event.start.format('x');
revertFunc(); // revert to get original duration
var numdays = Math.max(1, Math.round((event.end.format('x') - event.start.format('x')) / DAY_MS)) - 1;
event.start = moment(newstart);
event.end = moment(newstart + numdays * DAY_MS);
event.end.hours(settings.work_end || 18);
event.end.minutes(0);
if (event.end.diff(event.start) < 0)
event.end = new Date(newstart + HOUR_MS);
}
// send move request to server // send move request to server
var data = { var data = {
@ -3871,17 +3863,18 @@ function rcube_calendar_ui(settings)
calendar: event.calendar, calendar: event.calendar,
start: date2servertime(event.start), start: date2servertime(event.start),
end: date2servertime(event.end), end: date2servertime(event.end),
allDay: allday?1:0 allDay: event.allDay?1:0
}; };
update_event_confirm('move', event, data); update_event_confirm('move', event, data);
}, },
// callback for event resizing // callback for event resizing
eventResize: function(event, delta) { eventResize: function(event, delta) {
// sanitize event dates // sanitize event dates
if (event.allDay) if (event.allDay) {
event.start.hours(12); event.start.hours(12);
if (!event.end || event.end.diff(event.start) < 0) event.end.hour(13).subtract(1, 'days');
event.end = new Date(event.start.format('x') + HOUR_MS); }
// send resize request to server // send resize request to server
var data = { var data = {
@ -3891,6 +3884,7 @@ function rcube_calendar_ui(settings)
end: date2servertime(event.end), end: date2servertime(event.end),
allDay: event.allDay?1:0 allDay: event.allDay?1:0
}; };
update_event_confirm('resize', event, data); update_event_confirm('resize', event, data);
}, },
viewRender: function(view) { viewRender: function(view) {

View file

@ -81,7 +81,7 @@ function rcube_libcalendaring(settings)
// Support Moment.js objects // Support Moment.js objects
var start = 'toDate' in event.start ? event.start.toDate() : event.start, var start = 'toDate' in event.start ? event.start.toDate() : event.start,
end = 'toDate' in event.end ? event.end.toDate() : event.end; end = event.end && 'toDate' in event.end ? event.end.toDate() : event.end;
var fromto, duration = end.getTime() / 1000 - start.getTime() / 1000, var fromto, duration = end.getTime() / 1000 - start.getTime() / 1000,
until = voice ? ' ' + rcmail.gettext('until','libcalendaring') + ' ' : ' — '; until = voice ? ' ' + rcmail.gettext('until','libcalendaring') + ' ' : ' — ';
@ -240,6 +240,9 @@ function rcube_libcalendaring(settings)
*/ */
this.date2ISO8601 = function(date) this.date2ISO8601 = function(date)
{ {
if (!date)
return null;
if ('toDate' in date) if ('toDate' in date)
return date.format('YYYY-MM-DD[T]HH:mm:ss'); // MomentJS return date.format('YYYY-MM-DD[T]HH:mm:ss'); // MomentJS
@ -311,7 +314,7 @@ function rcube_libcalendaring(settings)
*/ */
this.date2unixtime = function(date) this.date2unixtime = function(date)
{ {
var dt = 'toDate' in date ? date.toDate() : date, var dt = date && 'toDate' in date ? date.toDate() : date,
dst_offset = (client_timezone - dt.getTimezoneOffset()) * 60; // adjust DST offset dst_offset = (client_timezone - dt.getTimezoneOffset()) * 60; // adjust DST offset
return Math.round(dt.getTime()/1000 + gmt_offset * 3600 + dst_offset); return Math.round(dt.getTime()/1000 + gmt_offset * 3600 + dst_offset);