Skip to content

Commit

Permalink
Handle opening newer event version than saved, #1355
Browse files Browse the repository at this point in the history
  • Loading branch information
charlag committed Aug 10, 2020
1 parent 9b3866e commit d754e52
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/calendar/CalendarEventViewModel.js
Expand Up @@ -841,6 +841,7 @@ export class CalendarEventViewModel {
// Using clone feels hacky but otherwise we need to save all attributes of the existing event somewhere and if dialog is
// cancelled we also don't want to modify passed event
const newEvent = this.existingEvent ? clone(this.existingEvent) : createCalendarEvent()
newEvent.sequence = incrementSequence(newEvent.sequence)

let startDate = new Date(this.startDate)
let endDate = new Date(this.endDate)
Expand Down
14 changes: 9 additions & 5 deletions src/calendar/CalendarInvites.js
Expand Up @@ -10,8 +10,7 @@ import type {CalendarEventAttendee} from "../api/entities/tutanota/CalendarEvent
import type {CalendarAttendeeStatusEnum, CalendarMethodEnum} from "../api/common/TutanotaConstants"
import {CalendarMethod, getAsEnumValue} from "../api/common/TutanotaConstants"
import {assertNotNull, clone} from "../api/common/utils/Utils"
import {findPrivateCalendar, getTimeZone, incrementSequence} from "./CalendarUtils"
import type {CalendarInfo} from "./CalendarView"
import {filterInt, findPrivateCalendar, getTimeZone} from "./CalendarUtils"
import {logins} from "../api/main/LoginController"
import {SendMailModel} from "../mail/SendMailModel"
import type {Mail} from "../api/entities/tutanota/Mail"
Expand Down Expand Up @@ -61,8 +60,14 @@ export function getLatestEvent(event: CalendarEvent): Promise<CalendarEvent> {
if (uid) {
return worker.getEventByUid(uid).then((existingEvent) => {
if (existingEvent) {
// It should be the latest version eventually via CalendarEventUpdates
return existingEvent
// If the file we are opening is newer than the one which we have on the server, update server version.
// Should not happen normally but can happen when e.g. reply and update were sent one after another before we accepted
// the invite. Then accepting first invite and then opening update should give us updated version.
if (filterInt(existingEvent.sequence) < filterInt(event.sequence)) {
return calendarModel.updateEventWithExternal(existingEvent, event)
} else {
return existingEvent
}
} else {
return event
}
Expand All @@ -84,7 +89,6 @@ export function replyToEventInvitation(
const eventClone = clone(event)
const foundAttendee = assertNotNull(eventClone.attendees.find((a) => a.address.address === attendee.address.address))
foundAttendee.status = decision
eventClone.sequence = incrementSequence(eventClone.sequence)

return Promise.all([
calendarModel.loadOrCreateCalendarInfo().then(findPrivateCalendar),
Expand Down
36 changes: 23 additions & 13 deletions src/calendar/CalendarModel.js
@@ -1,7 +1,7 @@
//@flow
import type {CalendarMonthTimeRange} from "./CalendarUtils"
import {
assignEventId, findPrivateCalendar,
assignEventId, filterInt, findPrivateCalendar,
getAllDayDateForTimezone,
getAllDayDateUTCFromZone,
getDiffInDays,
Expand Down Expand Up @@ -308,6 +308,11 @@ export interface CalendarModel {
loadCalendarInfos(): Promise<Map<Id, CalendarInfo>>;

loadOrCreateCalendarInfo(): Promise<Map<Id, CalendarInfo>>;

/**
* Update {@param dbEvent} stored on the server with {@param event} from the ics file.
*/
updateEventWithExternal(dbEvent: CalendarEvent, event: CalendarEvent): Promise<CalendarEvent>;
}

export class CalendarModelImpl implements CalendarModel {
Expand Down Expand Up @@ -497,18 +502,9 @@ export class CalendarModelImpl implements CalendarModel {
console.log("REQUEST sent not by organizer, ignoring")
return
}
const newEvent = clone(dbEvent)
newEvent.startTime = event.startTime
newEvent.endTime = event.endTime
newEvent.attendees = event.attendees
newEvent.summary = event.summary
newEvent.sequence = event.sequence
newEvent.location = event.location
newEvent.description = event.description
newEvent.organizer = event.organizer
newEvent.repeatRule = event.repeatRule
//console.log("Updating event", dbEvent.uid, dbEvent._id)
return this._updateEvent(dbEvent, newEvent)
if (filterInt(dbEvent.sequence) < filterInt(event.sequence)) {
return this.updateEventWithExternal(dbEvent, event).return()
}
}
})
} else if (calendarData.method === CalendarMethod.CANCEL) {
Expand All @@ -527,6 +523,20 @@ export class CalendarModelImpl implements CalendarModel {
}
}

updateEventWithExternal(dbEvent: CalendarEvent, event: CalendarEvent): Promise<CalendarEvent> {
const newEvent = clone(dbEvent)
newEvent.startTime = event.startTime
newEvent.endTime = event.endTime
newEvent.attendees = event.attendees
newEvent.summary = event.summary
newEvent.sequence = event.sequence
newEvent.location = event.location
newEvent.description = event.description
newEvent.organizer = event.organizer
newEvent.repeatRule = event.repeatRule
return this._updateEvent(dbEvent, newEvent).return(newEvent)
}

_updateEvent(dbEvent: CalendarEvent, newEvent: CalendarEvent): Promise<void> {
return Promise.all([
this.loadAlarms(dbEvent.alarmInfos, this._logins.getUserController().user),
Expand Down

0 comments on commit d754e52

Please sign in to comment.