MOBILE-3636 sync: Small improvements on previous sync services
parent
6d6cb0e36f
commit
a4225b8c02
|
@ -19,11 +19,13 @@ import { CoreSharedModule } from '@/core/shared.module';
|
||||||
import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
|
import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
|
||||||
|
|
||||||
import { AddonCalendarEditEventPage } from './edit-event.page';
|
import { AddonCalendarEditEventPage } from './edit-event.page';
|
||||||
|
import { CanLeaveGuard } from '@guards/can-leave';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: AddonCalendarEditEventPage,
|
component: AddonCalendarEditEventPage,
|
||||||
|
canDeactivate: [CanLeaveGuard],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CoreSyncBaseProvider } from '@classes/base-sync';
|
import { CoreSyncBaseProvider, CoreSyncBlockedError } from '@classes/base-sync';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CoreEvents } from '@singletons/events';
|
import { CoreEvents } from '@singletons/events';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
@ -27,9 +27,9 @@ import {
|
||||||
import { AddonCalendarOffline } from './calendar-offline';
|
import { AddonCalendarOffline } from './calendar-offline';
|
||||||
import { AddonCalendarHelper } from './calendar-helper';
|
import { AddonCalendarHelper } from './calendar-helper';
|
||||||
import { makeSingleton, Translate } from '@singletons';
|
import { makeSingleton, Translate } from '@singletons';
|
||||||
import { CoreError } from '@classes/errors/error';
|
|
||||||
import { CoreSync } from '@services/sync';
|
import { CoreSync } from '@services/sync';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
|
import { CoreNetworkError } from '@classes/errors/network-error';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service to sync calendar.
|
* Service to sync calendar.
|
||||||
|
@ -52,21 +52,23 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
|
||||||
* @param force Wether to force sync not depending on last execution.
|
* @param force Wether to force sync not depending on last execution.
|
||||||
* @return Promise resolved if sync is successful, rejected if sync fails.
|
* @return Promise resolved if sync is successful, rejected if sync fails.
|
||||||
*/
|
*/
|
||||||
async syncAllEvents(siteId?: string, force?: boolean): Promise<void> {
|
async syncAllEvents(siteId?: string, force = false): Promise<void> {
|
||||||
await this.syncOnSites('all calendar events', this.syncAllEventsFunc.bind(this, [force]), siteId);
|
await this.syncOnSites('all calendar events', this.syncAllEventsFunc.bind(this, [force]), siteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync all events on a site.
|
* Sync all events on a site.
|
||||||
*
|
*
|
||||||
* @param siteId Site ID to sync.
|
|
||||||
* @param force Wether to force sync not depending on last execution.
|
* @param force Wether to force sync not depending on last execution.
|
||||||
|
* @param siteId Site ID to sync.
|
||||||
* @return Promise resolved if sync is successful, rejected if sync fails.
|
* @return Promise resolved if sync is successful, rejected if sync fails.
|
||||||
*/
|
*/
|
||||||
protected async syncAllEventsFunc(siteId: string, force?: boolean): Promise<void> {
|
protected async syncAllEventsFunc(force = false, siteId?: string): Promise<void> {
|
||||||
const result = await (force ? this.syncEvents(siteId) : this.syncEventsIfNeeded(siteId));
|
const result = force
|
||||||
|
? await this.syncEvents(siteId)
|
||||||
|
: await this.syncEventsIfNeeded(siteId);
|
||||||
|
|
||||||
if (result && result.updated) {
|
if (result?.updated) {
|
||||||
// Sync successful, send event.
|
// Sync successful, send event.
|
||||||
CoreEvents.trigger<AddonCalendarSyncEvents>(AddonCalendarSyncProvider.AUTO_SYNCED, result, siteId);
|
CoreEvents.trigger<AddonCalendarSyncEvents>(AddonCalendarSyncProvider.AUTO_SYNCED, result, siteId);
|
||||||
}
|
}
|
||||||
|
@ -78,13 +80,13 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Promise resolved when the events are synced or if it doesn't need to be synced.
|
* @return Promise resolved when the events are synced or if it doesn't need to be synced.
|
||||||
*/
|
*/
|
||||||
async syncEventsIfNeeded(siteId?: string): Promise<void> {
|
async syncEventsIfNeeded(siteId?: string): Promise<AddonCalendarSyncEvents | undefined> {
|
||||||
siteId = siteId || CoreSites.instance.getCurrentSiteId();
|
siteId = siteId || CoreSites.instance.getCurrentSiteId();
|
||||||
|
|
||||||
const needed = await this.isSyncNeeded(AddonCalendarSyncProvider.SYNC_ID, siteId);
|
const needed = await this.isSyncNeeded(AddonCalendarSyncProvider.SYNC_ID, siteId);
|
||||||
|
|
||||||
if (needed) {
|
if (needed) {
|
||||||
await this.syncEvents(siteId);
|
return this.syncEvents(siteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,17 +127,12 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
|
||||||
updated: false,
|
updated: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let eventIds: number[] = [];
|
const eventIds: number[] = await CoreUtils.instance.ignoreErrors(AddonCalendarOffline.instance.getAllEventsIds(siteId), []);
|
||||||
try {
|
|
||||||
eventIds = await AddonCalendarOffline.instance.getAllEventsIds(siteId);
|
|
||||||
} catch {
|
|
||||||
// No offline data found.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eventIds.length > 0) {
|
if (eventIds.length > 0) {
|
||||||
if (!CoreApp.instance.isOnline()) {
|
if (!CoreApp.instance.isOnline()) {
|
||||||
// Cannot sync in offline.
|
// Cannot sync in offline.
|
||||||
throw new CoreError('Cannot sync while offline');
|
throw new CoreNetworkError();
|
||||||
}
|
}
|
||||||
|
|
||||||
const promises = eventIds.map((eventId) => this.syncOfflineEvent(eventId, result, siteId));
|
const promises = eventIds.map((eventId) => this.syncOfflineEvent(eventId, result, siteId));
|
||||||
|
@ -175,10 +172,10 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
|
||||||
if (CoreSync.instance.isBlocked(AddonCalendarProvider.COMPONENT, eventId, siteId)) {
|
if (CoreSync.instance.isBlocked(AddonCalendarProvider.COMPONENT, eventId, siteId)) {
|
||||||
this.logger.debug('Cannot sync event ' + eventId + ' because it is blocked.');
|
this.logger.debug('Cannot sync event ' + eventId + ' because it is blocked.');
|
||||||
|
|
||||||
throw Translate.instance.instant(
|
throw new CoreSyncBlockedError(Translate.instance.instant(
|
||||||
'core.errorsyncblocked',
|
'core.errorsyncblocked',
|
||||||
{ $a: Translate.instance.instant('addon.calendar.calendarevent') },
|
{ $a: Translate.instance.instant('addon.calendar.calendarevent') },
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// First of all, check if the event has been deleted.
|
// First of all, check if the event has been deleted.
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: ':courseId/:cmdId',
|
path: ':courseId/:cmId',
|
||||||
loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModBookIndexPageModule),
|
loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModBookIndexPageModule),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
(action)="expandDescription()" iconAction="fas-arrow-right">
|
(action)="expandDescription()" iconAction="fas-arrow-right">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}"
|
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}"
|
||||||
[iconAction]="'far-newspaper'" (action)="gotoBlog()">
|
iconAction="far-newspaper" (action)="gotoBlog()">
|
||||||
</core-context-menu-item>
|
</core-context-menu-item>
|
||||||
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
<core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
|
||||||
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
(action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: ':courseId/:cmdId',
|
path: ':courseId/:cmId',
|
||||||
loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModLessonIndexPageModule),
|
loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModLessonIndexPageModule),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -257,7 +257,7 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
|
||||||
*/
|
*/
|
||||||
protected async prefetchLesson(module: CoreCourseAnyModuleData, courseId?: number, single?: boolean): Promise<void> {
|
protected async prefetchLesson(module: CoreCourseAnyModuleData, courseId?: number, single?: boolean): Promise<void> {
|
||||||
const siteId = CoreSites.instance.getCurrentSiteId();
|
const siteId = CoreSites.instance.getCurrentSiteId();
|
||||||
courseId = courseId || module.course || 1;
|
courseId = courseId || module.course || CoreSites.instance.getCurrentSiteHomeId();
|
||||||
|
|
||||||
const commonOptions = {
|
const commonOptions = {
|
||||||
readingStrategy: CoreSitesReadingStrategy.OnlyNetwork,
|
readingStrategy: CoreSitesReadingStrategy.OnlyNetwork,
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreError } from '@classes/errors/error';
|
import { CoreSyncBlockedError } from '@classes/base-sync';
|
||||||
import { CoreNetworkError } from '@classes/errors/network-error';
|
import { CoreNetworkError } from '@classes/errors/network-error';
|
||||||
import { CoreCourseActivitySyncBaseProvider } from '@features/course/classes/activity-sync';
|
import { CoreCourseActivitySyncBaseProvider } from '@features/course/classes/activity-sync';
|
||||||
import { CoreCourse } from '@features/course/services/course';
|
import { CoreCourse } from '@features/course/services/course';
|
||||||
|
@ -122,7 +122,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
|
||||||
* @param force Wether to force sync not depending on last execution.
|
* @param force Wether to force sync not depending on last execution.
|
||||||
* @return Promise resolved if sync is successful, rejected if sync fails.
|
* @return Promise resolved if sync is successful, rejected if sync fails.
|
||||||
*/
|
*/
|
||||||
syncAllLessons(siteId?: string, force?: boolean): Promise<void> {
|
syncAllLessons(siteId?: string, force = false): Promise<void> {
|
||||||
return this.syncOnSites('all lessons', this.syncAllLessonsFunc.bind(this, !!force), siteId);
|
return this.syncOnSites('all lessons', this.syncAllLessonsFunc.bind(this, !!force), siteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
|
||||||
*/
|
*/
|
||||||
async syncLessonIfNeeded(
|
async syncLessonIfNeeded(
|
||||||
lessonId: number,
|
lessonId: number,
|
||||||
askPassword?: boolean,
|
askPassword = false,
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<AddonModLessonSyncResult | undefined> {
|
): Promise<AddonModLessonSyncResult | undefined> {
|
||||||
const needed = await this.isSyncNeeded(lessonId, siteId);
|
const needed = await this.isSyncNeeded(lessonId, siteId);
|
||||||
|
@ -184,8 +184,8 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
|
||||||
*/
|
*/
|
||||||
async syncLesson(
|
async syncLesson(
|
||||||
lessonId: number,
|
lessonId: number,
|
||||||
askPassword?: boolean,
|
askPassword = false,
|
||||||
ignoreBlock?: boolean,
|
ignoreBlock = false,
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<AddonModLessonSyncResult> {
|
): Promise<AddonModLessonSyncResult> {
|
||||||
siteId = siteId || CoreSites.instance.getCurrentSiteId();
|
siteId = siteId || CoreSites.instance.getCurrentSiteId();
|
||||||
|
@ -201,7 +201,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
|
||||||
if (!ignoreBlock && CoreSync.instance.isBlocked(AddonModLessonProvider.COMPONENT, lessonId, siteId)) {
|
if (!ignoreBlock && CoreSync.instance.isBlocked(AddonModLessonProvider.COMPONENT, lessonId, siteId)) {
|
||||||
this.logger.debug('Cannot sync lesson ' + lessonId + ' because it is blocked.');
|
this.logger.debug('Cannot sync lesson ' + lessonId + ' because it is blocked.');
|
||||||
|
|
||||||
throw new CoreError(Translate.instance.instant('core.errorsyncblocked', { $a: this.componentTranslate }));
|
throw new CoreSyncBlockedError(Translate.instance.instant('core.errorsyncblocked', { $a: this.componentTranslate }));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.debug('Try to sync lesson ' + lessonId + ' in site ' + siteId);
|
this.logger.debug('Try to sync lesson ' + lessonId + ' in site ' + siteId);
|
||||||
|
@ -222,8 +222,8 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
|
||||||
*/
|
*/
|
||||||
protected async performSyncLesson(
|
protected async performSyncLesson(
|
||||||
lessonId: number,
|
lessonId: number,
|
||||||
askPassword?: boolean,
|
askPassword = false,
|
||||||
ignoreBlock?: boolean,
|
ignoreBlock = false,
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<AddonModLessonSyncResult> {
|
): Promise<AddonModLessonSyncResult> {
|
||||||
// Sync offline logs.
|
// Sync offline logs.
|
||||||
|
@ -270,7 +270,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
|
||||||
protected async syncAttempts(
|
protected async syncAttempts(
|
||||||
lessonId: number,
|
lessonId: number,
|
||||||
result: AddonModLessonSyncResult,
|
result: AddonModLessonSyncResult,
|
||||||
askPassword?: boolean,
|
askPassword = false,
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<AddonModLessonGetPasswordResult | undefined> {
|
): Promise<AddonModLessonGetPasswordResult | undefined> {
|
||||||
let attempts = await AddonModLessonOffline.instance.getLessonAttempts(lessonId, siteId);
|
let attempts = await AddonModLessonOffline.instance.getLessonAttempts(lessonId, siteId);
|
||||||
|
@ -408,8 +408,8 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
|
||||||
lessonId: number,
|
lessonId: number,
|
||||||
result: AddonModLessonSyncResult,
|
result: AddonModLessonSyncResult,
|
||||||
passwordData?: AddonModLessonGetPasswordResult,
|
passwordData?: AddonModLessonGetPasswordResult,
|
||||||
askPassword?: boolean,
|
askPassword = false,
|
||||||
ignoreBlock?: boolean,
|
ignoreBlock = false,
|
||||||
siteId?: string,
|
siteId?: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Attempts sent or there was none. If there is a finished retake, send it.
|
// Attempts sent or there was none. If there is a finished retake, send it.
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: ':courseId/:cmdId',
|
path: ':courseId/:cmId',
|
||||||
loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModPageIndexPageModule),
|
loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModPageIndexPageModule),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -231,7 +231,7 @@ export class CoreSyncBaseProvider<T = void> {
|
||||||
* @param time Time to set. If not defined, current time.
|
* @param time Time to set. If not defined, current time.
|
||||||
* @return Promise resolved when the time is set.
|
* @return Promise resolved when the time is set.
|
||||||
*/
|
*/
|
||||||
async setSyncTime(id: string, siteId?: string, time?: number): Promise<void> {
|
async setSyncTime(id: string | number, siteId?: string, time?: number): Promise<void> {
|
||||||
time = typeof time != 'undefined' ? time : Date.now();
|
time = typeof time != 'undefined' ? time : Date.now();
|
||||||
|
|
||||||
await CoreSync.instance.insertOrUpdateSyncRecord(this.component, id, { time: time }, siteId);
|
await CoreSync.instance.insertOrUpdateSyncRecord(this.component, id, { time: time }, siteId);
|
||||||
|
@ -245,7 +245,7 @@ export class CoreSyncBaseProvider<T = void> {
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
async setSyncWarnings(id: string, warnings: string[], siteId?: string): Promise<void> {
|
async setSyncWarnings(id: string | number, warnings: string[], siteId?: string): Promise<void> {
|
||||||
const warningsText = JSON.stringify(warnings || []);
|
const warningsText = JSON.stringify(warnings || []);
|
||||||
|
|
||||||
await CoreSync.instance.insertOrUpdateSyncRecord(this.component, id, { warnings: warningsText }, siteId);
|
await CoreSync.instance.insertOrUpdateSyncRecord(this.component, id, { warnings: warningsText }, siteId);
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { CoreCourseModulePrefetchHandlerBase } from './module-prefetch-handler';
|
||||||
/**
|
/**
|
||||||
* Base class to create activity sync providers. It provides some common functions.
|
* Base class to create activity sync providers. It provides some common functions.
|
||||||
*/
|
*/
|
||||||
export class CoreCourseActivitySyncBaseProvider<T> extends CoreSyncBaseProvider<T> {
|
export class CoreCourseActivitySyncBaseProvider<T = void> extends CoreSyncBaseProvider<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conveniece function to prefetch data after an update.
|
* Conveniece function to prefetch data after an update.
|
||||||
|
|
|
@ -112,11 +112,16 @@ export class CoreSyncProvider {
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Promise resolved with done.
|
* @return Promise resolved with done.
|
||||||
*/
|
*/
|
||||||
async insertOrUpdateSyncRecord(component: string, id: string, data: Partial<CoreSyncRecord>, siteId?: string): Promise<void> {
|
async insertOrUpdateSyncRecord(
|
||||||
|
component: string,
|
||||||
|
id: string | number,
|
||||||
|
data: Partial<CoreSyncRecord>,
|
||||||
|
siteId?: string,
|
||||||
|
): Promise<void> {
|
||||||
const db = await CoreSites.instance.getSiteDb(siteId);
|
const db = await CoreSites.instance.getSiteDb(siteId);
|
||||||
|
|
||||||
data.component = component;
|
data.component = component;
|
||||||
data.id = id;
|
data.id = id + '';
|
||||||
|
|
||||||
await db.insertRecord(SYNC_TABLE_NAME, data);
|
await db.insertRecord(SYNC_TABLE_NAME, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1607,7 +1607,7 @@ export class CoreUtilsProvider {
|
||||||
const result = await promise;
|
const result = await promise;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Ignore errors.
|
// Ignore errors.
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue