Merge pull request #2059 from dpalou/MOBILE-3090
MOBILE-3090 calendar: Improve invalidate data after sync
This commit is contained in:
		
						commit
						373a4d0cc7
					
				| @ -479,7 +479,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (formData.repeat) { |         if (formData.repeat) { | ||||||
|             data.repeats = formData.repeats; |             data.repeats = Number(formData.repeats); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (this.event && this.event.repeatid) { |         if (this.event && this.event.repeatid) { | ||||||
| @ -489,15 +489,22 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy { | |||||||
| 
 | 
 | ||||||
|         // Send the data.
 |         // Send the data.
 | ||||||
|         const modal = this.domUtils.showModalLoading('core.sending', true); |         const modal = this.domUtils.showModalLoading('core.sending', true); | ||||||
|  |         let event; | ||||||
| 
 | 
 | ||||||
|         this.calendarProvider.submitEvent(this.eventId, data).then((result) => { |         this.calendarProvider.submitEvent(this.eventId, data).then((result) => { | ||||||
|             const numberOfRepetitions = formData.repeat ? formData.repeats : |             event = result.event; | ||||||
|                 (data.repeateditall && this.event.othereventscount ? this.event.othereventscount + 1 : 1); | 
 | ||||||
|             this.calendarHelper.invalidateRepeatedEventsOnCalendar(result.event, numberOfRepetitions).catch(() => { |             if (result.sent) { | ||||||
|                 // Ignore errors.
 |                 // Event created or edited, invalidate right days & months.
 | ||||||
|             }).then(() => { |                 const numberOfRepetitions = formData.repeat ? formData.repeats : | ||||||
|                 this.returnToList(result.event); |                     (data.repeateditall && this.event.othereventscount ? this.event.othereventscount + 1 : 1); | ||||||
|             }); | 
 | ||||||
|  |                 this.calendarHelper.invalidateRepeatedEventsOnCalendarForEvent(result.event, numberOfRepetitions).catch(() => { | ||||||
|  |                     // Ignore errors.
 | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         }).then(() => { | ||||||
|  |             this.returnToList(event); | ||||||
|         }).catch((error) => { |         }).catch((error) => { | ||||||
|             this.domUtils.showErrorModalDefault(error, 'Error sending data.'); |             this.domUtils.showErrorModalDefault(error, 'Error sending data.'); | ||||||
|         }).finally(() => { |         }).finally(() => { | ||||||
|  | |||||||
| @ -445,10 +445,19 @@ export class AddonCalendarEventPage implements OnDestroy { | |||||||
|             const modal = this.domUtils.showModalLoading('core.sending', true); |             const modal = this.domUtils.showModalLoading('core.sending', true); | ||||||
| 
 | 
 | ||||||
|             this.calendarProvider.deleteEvent(this.event.id, this.event.name, deleteAll).then((sent) => { |             this.calendarProvider.deleteEvent(this.event.id, this.event.name, deleteAll).then((sent) => { | ||||||
|                 this.calendarHelper.invalidateRepeatedEventsOnCalendar(this.event, deleteAll ? this.event.eventcount : 1) |                 let promise; | ||||||
|                         .catch(() => { | 
 | ||||||
|                     // Ignore errors.
 |                 if (sent) { | ||||||
|                 }).then(() => { |                     // Event deleted, invalidate right days & months.
 | ||||||
|  |                     promise = this.calendarHelper.invalidateRepeatedEventsOnCalendarForEvent(this.event, | ||||||
|  |                             deleteAll ? this.event.eventcount : 1).catch(() => { | ||||||
|  |                         // Ignore errors.
 | ||||||
|  |                     }); | ||||||
|  |                 } else { | ||||||
|  |                     promise = Promise.resolve(); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 return promise.then(() => { | ||||||
|                     // Trigger an event.
 |                     // Trigger an event.
 | ||||||
|                     this.eventsProvider.trigger(AddonCalendarProvider.DELETED_EVENT_EVENT, { |                     this.eventsProvider.trigger(AddonCalendarProvider.DELETED_EVENT_EVENT, { | ||||||
|                         eventId: this.eventId, |                         eventId: this.eventId, | ||||||
|  | |||||||
| @ -95,7 +95,7 @@ export class AddonCalendarOfflineProvider { | |||||||
|                     }, |                     }, | ||||||
|                     { |                     { | ||||||
|                         name: 'repeats', |                         name: 'repeats', | ||||||
|                         type: 'TEXT', |                         type: 'INTEGER', | ||||||
|                     }, |                     }, | ||||||
|                     { |                     { | ||||||
|                         name: 'repeatid', |                         name: 'repeatid', | ||||||
|  | |||||||
| @ -26,6 +26,7 @@ import { CoreTimeUtilsProvider } from '@providers/utils/time'; | |||||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||||
| import { AddonCalendarProvider } from './calendar'; | import { AddonCalendarProvider } from './calendar'; | ||||||
| import { AddonCalendarOfflineProvider } from './calendar-offline'; | import { AddonCalendarOfflineProvider } from './calendar-offline'; | ||||||
|  | import { AddonCalendarHelperProvider } from './helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Service to sync calendar. |  * Service to sync calendar. | ||||||
| @ -48,7 +49,8 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider { | |||||||
|             timeUtils: CoreTimeUtilsProvider, |             timeUtils: CoreTimeUtilsProvider, | ||||||
|             private utils: CoreUtilsProvider, |             private utils: CoreUtilsProvider, | ||||||
|             private calendarProvider: AddonCalendarProvider, |             private calendarProvider: AddonCalendarProvider, | ||||||
|             private calendarOffline: AddonCalendarOfflineProvider) { |             private calendarOffline: AddonCalendarOfflineProvider, | ||||||
|  |             private calendarHelper: AddonCalendarHelperProvider) { | ||||||
| 
 | 
 | ||||||
|         super('AddonCalendarSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, |         super('AddonCalendarSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, | ||||||
|                 timeUtils); |                 timeUtils); | ||||||
| @ -124,6 +126,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider { | |||||||
|             warnings: [], |             warnings: [], | ||||||
|             events: [], |             events: [], | ||||||
|             deleted: [], |             deleted: [], | ||||||
|  |             toinvalidate: [], | ||||||
|             updated: false |             updated: false | ||||||
|         }; |         }; | ||||||
|         let offlineEventIds: number[]; |         let offlineEventIds: number[]; | ||||||
| @ -152,18 +155,13 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider { | |||||||
|             return this.utils.allPromises(promises); |             return this.utils.allPromises(promises); | ||||||
|         }).then(() => { |         }).then(() => { | ||||||
|             if (result.updated) { |             if (result.updated) { | ||||||
|  | 
 | ||||||
|                 // Data has been sent to server. Now invalidate the WS calls.
 |                 // Data has been sent to server. Now invalidate the WS calls.
 | ||||||
|                 const promises = [ |                 const promises = [ | ||||||
|                     this.calendarProvider.invalidateEventsList(siteId), |                     this.calendarProvider.invalidateEventsList(siteId), | ||||||
|  |                     this.calendarHelper.invalidateRepeatedEventsOnCalendar(result.toinvalidate, siteId) | ||||||
|                 ]; |                 ]; | ||||||
| 
 | 
 | ||||||
|                 offlineEventIds.forEach((eventId) => { |  | ||||||
|                     if (eventId > 0) { |  | ||||||
|                         // An event was edited, invalidate its data too.
 |  | ||||||
|                         promises.push(this.calendarProvider.invalidateEvent(eventId, siteId)); |  | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
| 
 |  | ||||||
|                 return Promise.all(promises).catch(() => { |                 return Promise.all(promises).catch(() => { | ||||||
|                     // Ignore errors.
 |                     // Ignore errors.
 | ||||||
|                 }); |                 }); | ||||||
| @ -214,6 +212,16 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider { | |||||||
|                     // Ignore errors, maybe there was no edit data.
 |                     // Ignore errors, maybe there was no edit data.
 | ||||||
|                 })); |                 })); | ||||||
| 
 | 
 | ||||||
|  |                 // We need the event data to invalidate it. Get it from local DB.
 | ||||||
|  |                 promises.push(this.calendarProvider.getEventFromLocalDb(eventId, siteId).then((event) => { | ||||||
|  |                     result.toinvalidate.push({ | ||||||
|  |                         event: event, | ||||||
|  |                         repeated: data.repeat ? event.eventcount : 1 | ||||||
|  |                     }); | ||||||
|  |                 }).catch(() => { | ||||||
|  |                     // Ignore errors.
 | ||||||
|  |                 })); | ||||||
|  | 
 | ||||||
|                 return Promise.all(promises); |                 return Promise.all(promises); | ||||||
|             }).catch((error) => { |             }).catch((error) => { | ||||||
| 
 | 
 | ||||||
| @ -257,6 +265,15 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider { | |||||||
|                     result.updated = true; |                     result.updated = true; | ||||||
|                     result.events.push(newEvent); |                     result.events.push(newEvent); | ||||||
| 
 | 
 | ||||||
|  |                     // Add data to invalidate.
 | ||||||
|  |                     const numberOfRepetitions = data.repeat ? data.repeats : | ||||||
|  |                         (data.repeateditall && newEvent.repeatid ? newEvent.eventcount : 1); | ||||||
|  | 
 | ||||||
|  |                     result.toinvalidate.push({ | ||||||
|  |                         event: newEvent, | ||||||
|  |                         repeated: numberOfRepetitions | ||||||
|  |                     }); | ||||||
|  | 
 | ||||||
|                     // Event sent, delete the offline data.
 |                     // Event sent, delete the offline data.
 | ||||||
|                     return this.calendarOffline.deleteEvent(event.id, siteId); |                     return this.calendarOffline.deleteEvent(event.id, siteId); | ||||||
|                 }).catch((error) => { |                 }).catch((error) => { | ||||||
|  | |||||||
| @ -344,73 +344,100 @@ export class AddonCalendarHelperProvider { | |||||||
|     /** |     /** | ||||||
|      * Invalidate all calls from calendar WS calls. |      * Invalidate all calls from calendar WS calls. | ||||||
|      * |      * | ||||||
|      * @param  {any}          event     Event that has been touched. |      * @param {{event: any, repeated: number}[]} events Events that have been touched and number of times each event is repeated. | ||||||
|      * @param  {number}      repeated   Number of times the event is repeated. |  | ||||||
|      * @param {string} [siteId] Site ID. If not defined, current site. |      * @param {string} [siteId] Site ID. If not defined, current site. | ||||||
|      * @return {Promise<any>}           REsolved when done. |      * @return {Promise<any>} Resolved when done. | ||||||
|      */ |      */ | ||||||
|     invalidateRepeatedEventsOnCalendar(event: any, repeated: number, siteId?: string): Promise<any> { |     invalidateRepeatedEventsOnCalendar(events: {event: any, repeated: number}[], siteId?: string): Promise<any> { | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             let invalidatePromise; |  | ||||||
|             const timestarts = []; |             const timestarts = []; | ||||||
| 
 | 
 | ||||||
|             if (repeated > 1) { |             // Invalidate the events and get the timestarts so we can invalidate months & days.
 | ||||||
|                 if (event.repeatid) { |             return this.utils.allPromises(events.map((eventData) => { | ||||||
|                     // Being edited or deleted.
 |  | ||||||
|                     invalidatePromise = this.calendarProvider.getLocalEventsByRepeatIdFromLocalDb(event.repeatid, site.id) |  | ||||||
|                             .then((events) => { |  | ||||||
|                         return this.utils.allPromises(events.map((event) => { |  | ||||||
|                             timestarts.push(event.timestart); |  | ||||||
| 
 | 
 | ||||||
|                             return this.calendarProvider.invalidateEvent(event.id); |                 if (eventData.repeated > 1) { | ||||||
|                         })); |                     if (eventData.event.repeatid) { | ||||||
|                     }); |                         // Being edited or deleted.
 | ||||||
|                 } else { |                         // We need to calculate the days to invalidate because the event date could have changed.
 | ||||||
|                     // Being added.
 |                         // We don't know if the repeated events are before or after this one, invalidate them all.
 | ||||||
|                     let time = event.timestart; |                         timestarts.push(eventData.event.timestart); | ||||||
|                     while (repeated > 0) { | 
 | ||||||
|                         timestarts.push(time); |                         for (let i = 1; i < eventData.repeated; i++) { | ||||||
|                         time += CoreConstants.SECONDS_DAY * 7; |                             timestarts.push(eventData.event.timestart + CoreConstants.SECONDS_DAY * 7 * i); | ||||||
|                         repeated--; |                             timestarts.push(eventData.event.timestart - CoreConstants.SECONDS_DAY * 7 * i); | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         // Get the repeated events to invalidate them.
 | ||||||
|  |                         return this.calendarProvider.getLocalEventsByRepeatIdFromLocalDb(eventData.event.repeatid, site.id) | ||||||
|  |                                 .then((events) => { | ||||||
|  | 
 | ||||||
|  |                             return this.utils.allPromises(events.map((event) => { | ||||||
|  |                                 return this.calendarProvider.invalidateEvent(event.id); | ||||||
|  |                             })); | ||||||
|  |                         }); | ||||||
|  |                     } else { | ||||||
|  |                         // Being added.
 | ||||||
|  |                         let time = eventData.event.timestart; | ||||||
|  |                         while (eventData.repeated > 0) { | ||||||
|  |                             timestarts.push(time); | ||||||
|  |                             time += CoreConstants.SECONDS_DAY * 7; | ||||||
|  |                             eventData.repeated--; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         return Promise.resolve(); | ||||||
|                     } |                     } | ||||||
|  |                 } else { | ||||||
|  |                     // Not repeated.
 | ||||||
|  |                     timestarts.push(eventData.event.timestart); | ||||||
| 
 | 
 | ||||||
|                     invalidatePromise = Promise.resolve(); |                     return this.calendarProvider.invalidateEvent(eventData.event.id); | ||||||
|                 } |                 } | ||||||
|             } else { |  | ||||||
|                 // Not repeated.
 |  | ||||||
|                 timestarts.push(event.timestart); |  | ||||||
|                 invalidatePromise = this.calendarProvider.invalidateEvent(event.id); |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             return invalidatePromise.finally(() => { |             })).finally(() => { | ||||||
|                 let lastMonth, lastYear; |                 const invalidatedMonths = {}, | ||||||
|  |                     invalidatedDays = {}; | ||||||
| 
 | 
 | ||||||
|                 return this.utils.allPromises([ |                 return this.utils.allPromises([ | ||||||
|                     this.calendarProvider.invalidateAllUpcomingEvents(), |                     this.calendarProvider.invalidateAllUpcomingEvents(), | ||||||
| 
 | 
 | ||||||
|                     // Invalidate months.
 |                     // Invalidate months and days.
 | ||||||
|                     this.utils.allPromises(timestarts.map((time) => { |                     this.utils.allPromises(timestarts.map((time) => { | ||||||
|                         const day = moment(new Date(time * 1000)); |                         const promises = [], | ||||||
|  |                             day = moment(new Date(time * 1000)), | ||||||
|  |                             monthId = this.getMonthId(day.year(), day.month() + 1), | ||||||
|  |                             dayId = monthId + '#' + day.date(); | ||||||
| 
 | 
 | ||||||
|                         if (lastMonth && (lastMonth == day.month() + 1 && lastYear == day.year())) { |                         if (!invalidatedMonths[monthId]) { | ||||||
|                             return Promise.resolve(); |                             // Month not invalidated already, do it now.
 | ||||||
|  |                             invalidatedMonths[monthId] = monthId; | ||||||
|  | 
 | ||||||
|  |                             promises.push(this.calendarProvider.invalidateMonthlyEvents(day.year(), day.month() + 1, site.id)); | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|                         // Invalidate once.
 |                         if (!invalidatedDays[dayId]) { | ||||||
|                         lastMonth = day.month() + 1; |                             // Day not invalidated already, do it now.
 | ||||||
|                         lastYear = day.year(); |                             invalidatedDays[dayId] = dayId; | ||||||
| 
 | 
 | ||||||
|                         return this.calendarProvider.invalidateMonthlyEvents(lastYear, lastMonth, site.id); |                             promises.push(this.calendarProvider.invalidateDayEvents(day.year(), day.month() + 1, day.date(), | ||||||
|                     })), |                                     site.id)); | ||||||
|  |                         } | ||||||
| 
 | 
 | ||||||
|                     // Invalidate days.
 |                         return this.utils.allPromises(promises); | ||||||
|                     this.utils.allPromises(timestarts.map((time) => { |                     })) | ||||||
|                         const day = moment(new Date(time * 1000)); |  | ||||||
| 
 |  | ||||||
|                         return this.calendarProvider.invalidateDayEvents(day.year(), day.month() + 1, day.date(), site.id); |  | ||||||
|                     })), |  | ||||||
|                 ]); |                 ]); | ||||||
|             }); |             }); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Invalidate all calls from calendar WS calls. | ||||||
|  |      * | ||||||
|  |      * @param {any} event Event that has been touched. | ||||||
|  |      * @param {number} repeated Number of times the event is repeated. | ||||||
|  |      * @param {string} [siteId] Site ID. If not defined, current site. | ||||||
|  |      * @return {Promise<any>} Resolved when done. | ||||||
|  |      */ | ||||||
|  |     invalidateRepeatedEventsOnCalendarForEvent(event: any, repeated: number, siteId?: string): Promise<any> { | ||||||
|  |         return this.invalidateRepeatedEventsOnCalendar([{event: event, repeated: repeated}], siteId); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user