Merge pull request #2059 from dpalou/MOBILE-3090
MOBILE-3090 calendar: Improve invalidate data after syncmain
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…
Reference in New Issue