Fix all-day events covering a timezone change
parent
e5c71a4179
commit
cbf9b6da3e
|
@ -328,30 +328,10 @@
|
|||
*/
|
||||
- (NSDictionary *) attributesInContext: (WOContext *) context
|
||||
{
|
||||
BOOL isAllDay;
|
||||
NSCalendarDate *eventStartDate, *eventEndDate;
|
||||
NSMutableDictionary *data;
|
||||
NSTimeZone *timeZone;
|
||||
SOGoUserDefaults *ud;
|
||||
|
||||
isAllDay = [self isAllDay];
|
||||
ud = [[context activeUser] userDefaults];
|
||||
timeZone = [ud timeZone];
|
||||
eventStartDate = [self startDate];
|
||||
eventEndDate = [self endDate];
|
||||
|
||||
if (!isAllDay)
|
||||
{
|
||||
[eventStartDate setTimeZone: timeZone];
|
||||
[eventEndDate setTimeZone: timeZone];
|
||||
}
|
||||
|
||||
data = [NSMutableDictionary dictionaryWithDictionary: [super attributesInContext: context]];
|
||||
|
||||
[data setObject: [eventStartDate iso8601DateString] forKey: @"startDate"];
|
||||
[data setObject: [eventEndDate iso8601DateString] forKey: @"endDate"];
|
||||
|
||||
[data setObject: [NSNumber numberWithBool: isAllDay] forKey: @"isAllDay"];
|
||||
[data setObject: [NSNumber numberWithBool: ![self isOpaque]] forKey: @"isTransparent"];
|
||||
|
||||
return data;
|
||||
|
@ -383,18 +363,10 @@
|
|||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
aptStartDate = [self dateFromString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"startTime"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
[self adjustDate: &aptStartDate withTimeString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"endDate"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
aptEndDate = [self dateFromString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"endTime"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
[self adjustDate: &aptEndDate withTimeString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"isTransparent"];
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
[self setTransparency: ([o boolValue]? @"TRANSPARENT" : @"OPAQUE")];
|
||||
|
@ -418,6 +390,14 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
o = [data objectForKey: @"startTime"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
[self adjustDate: &aptStartDate withTimeString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"endTime"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
[self adjustDate: &aptEndDate withTimeString: o inContext: context];
|
||||
|
||||
[self setStartDate: aptStartDate];
|
||||
[self setEndDate: aptEndDate];
|
||||
}
|
||||
|
|
|
@ -652,7 +652,8 @@
|
|||
iCalEvent *event;
|
||||
|
||||
BOOL resetAlarm;
|
||||
unsigned int snoozeAlarm;
|
||||
NSInteger offset;
|
||||
NSUInteger snoozeAlarm;
|
||||
|
||||
event = [self event];
|
||||
co = [self clientObject];
|
||||
|
@ -662,12 +663,23 @@
|
|||
timeZone = [ud timeZone];
|
||||
eventStartDate = [event startDate];
|
||||
eventEndDate = [event endDate];
|
||||
if (!isAllDay)
|
||||
|
||||
if (isAllDay)
|
||||
{
|
||||
[eventStartDate setTimeZone: timeZone];
|
||||
[eventEndDate setTimeZone: timeZone];
|
||||
eventEndDate = [eventEndDate dateByAddingYears: 0 months: 0 days: -1];
|
||||
|
||||
// Convert the dates to the user's timezone
|
||||
offset = [timeZone secondsFromGMTForDate: eventStartDate];
|
||||
eventStartDate = [eventStartDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
offset = [timeZone secondsFromGMTForDate: eventEndDate];
|
||||
eventEndDate = [eventEndDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
}
|
||||
|
||||
[eventStartDate setTimeZone: timeZone];
|
||||
[eventEndDate setTimeZone: timeZone];
|
||||
|
||||
// resetAlarm=yes is set only when we are about to show the alarm popup in the Web
|
||||
// interface of SOGo. See generic.js for details. snoozeAlarm=X is called when the
|
||||
// user clicks on "Snooze for" X minutes, when the popup is being displayed.
|
||||
|
@ -704,8 +716,11 @@
|
|||
data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
[componentCalendar nameInContainer], @"pid",
|
||||
[componentCalendar displayName], @"calendar",
|
||||
[NSNumber numberWithBool: isAllDay], @"isAllDay",
|
||||
[NSNumber numberWithBool: [self isReadOnly]], @"isReadOnly",
|
||||
[NSNumber numberWithBool: [self userHasRSVP]], @"userHasRSVP",
|
||||
[eventStartDate iso8601DateString], @"startDate",
|
||||
[eventEndDate iso8601DateString], @"endDate",
|
||||
[dateFormatter formattedDate: eventStartDate], @"localizedStartDate",
|
||||
[dateFormatter formattedDate: eventEndDate], @"localizedEndDate",
|
||||
[self alarm], @"alarm",
|
||||
|
|
|
@ -184,6 +184,15 @@ Date.prototype.daysUpTo = function(otherDate) {
|
|||
return days;
|
||||
};
|
||||
|
||||
Date.prototype.minutesTo = function(otherDate) {
|
||||
var delta, dstOffset;
|
||||
|
||||
delta = Math.floor(otherDate.valueOf() - this.valueOf())/1000/60;
|
||||
dstOffset = otherDate.getTimezoneOffset() - this.getTimezoneOffset();
|
||||
|
||||
return delta - dstOffset;
|
||||
};
|
||||
|
||||
Date.prototype.stringWithSeparator = function(separator) {
|
||||
var month = '' + (this.getMonth() + 1);
|
||||
var day = '' + this.getDate();
|
||||
|
|
|
@ -422,13 +422,10 @@
|
|||
|
||||
if (this.endDate) {
|
||||
this.end = new Date(this.endDate.substring(0,10) + ' ' + this.endDate.substring(11,16));
|
||||
this.delta = Math.floor((Math.abs(this.end - this.start)/1000)/60);
|
||||
this.delta = this.start.minutesTo(this.end);
|
||||
}
|
||||
else if (this.type == 'appointment') {
|
||||
this.end = new Date(this.start.getTime());
|
||||
this.end.setMinutes(Math.round(this.end.getMinutes()/15)*15);
|
||||
this.end.addMinutes(this.delta);
|
||||
//this.end.addMinutes(this.delta);
|
||||
this.setDelta(this.delta);
|
||||
}
|
||||
|
||||
if (this.dueDate)
|
||||
|
@ -650,6 +647,19 @@
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @function setDelta
|
||||
* @memberof Component.prototype
|
||||
* @desc Set the end time to the specified number of minutes after the start time.
|
||||
* @param {number} delta - the number of minutes
|
||||
*/
|
||||
Component.prototype.setDelta = function(delta) {
|
||||
this.delta = delta;
|
||||
this.end = new Date(this.start.getTime());
|
||||
this.end.setMinutes(Math.round(this.end.getMinutes()/15)*15);
|
||||
this.end.addMinutes(this.delta);
|
||||
};
|
||||
|
||||
/**
|
||||
* @function updateFreeBusy
|
||||
* @memberof Component.prototype
|
||||
|
|
|
@ -299,11 +299,11 @@
|
|||
|
||||
function adjustEndTime() {
|
||||
// The end date must be after the start date
|
||||
var delta = vm.component.end.valueOf() - vm.component.start.valueOf();
|
||||
var delta = vm.component.start.minutesTo(vm.component.end);
|
||||
if (delta < 0)
|
||||
vm.component.end = new Date(oldEndDate.getTime());
|
||||
else {
|
||||
vm.component.delta = Math.floor((Math.abs(vm.component.end - vm.component.start)/1000)/60);
|
||||
vm.component.delta = delta;
|
||||
oldEndDate = new Date(vm.component.end.getTime());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue