forked from CIT/Vmeda.Online
		
	MOBILE-3636 sync: Small improvements on previous sync services
This commit is contained in:
		
							parent
							
								
									6d6cb0e36f
								
							
						
					
					
						commit
						a4225b8c02
					
				@ -19,11 +19,13 @@ import { CoreSharedModule } from '@/core/shared.module';
 | 
			
		||||
import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
 | 
			
		||||
 | 
			
		||||
import { AddonCalendarEditEventPage } from './edit-event.page';
 | 
			
		||||
import { CanLeaveGuard } from '@guards/can-leave';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
    {
 | 
			
		||||
        path: '',
 | 
			
		||||
        component: AddonCalendarEditEventPage,
 | 
			
		||||
        canDeactivate: [CanLeaveGuard],
 | 
			
		||||
    },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { CoreSyncBaseProvider } from '@classes/base-sync';
 | 
			
		||||
import { CoreSyncBaseProvider, CoreSyncBlockedError } from '@classes/base-sync';
 | 
			
		||||
import { CoreApp } from '@services/app';
 | 
			
		||||
import { CoreEvents } from '@singletons/events';
 | 
			
		||||
import { CoreSites } from '@services/sites';
 | 
			
		||||
@ -27,9 +27,9 @@ import {
 | 
			
		||||
import { AddonCalendarOffline } from './calendar-offline';
 | 
			
		||||
import { AddonCalendarHelper } from './calendar-helper';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons';
 | 
			
		||||
import { CoreError } from '@classes/errors/error';
 | 
			
		||||
import { CoreSync } from '@services/sync';
 | 
			
		||||
import { CoreTextUtils } from '@services/utils/text';
 | 
			
		||||
import { CoreNetworkError } from '@classes/errors/network-error';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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.
 | 
			
		||||
     * @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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sync all events on a site.
 | 
			
		||||
     *
 | 
			
		||||
     * @param siteId Site ID to sync.
 | 
			
		||||
     * @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.
 | 
			
		||||
     */
 | 
			
		||||
    protected async syncAllEventsFunc(siteId: string, force?: boolean): Promise<void> {
 | 
			
		||||
        const result = await (force ? this.syncEvents(siteId) : this.syncEventsIfNeeded(siteId));
 | 
			
		||||
    protected async syncAllEventsFunc(force = false, siteId?: string): Promise<void> {
 | 
			
		||||
        const result = force
 | 
			
		||||
            ? await this.syncEvents(siteId)
 | 
			
		||||
            : await this.syncEventsIfNeeded(siteId);
 | 
			
		||||
 | 
			
		||||
        if (result && result.updated) {
 | 
			
		||||
        if (result?.updated) {
 | 
			
		||||
            // Sync successful, send event.
 | 
			
		||||
            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.
 | 
			
		||||
     * @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();
 | 
			
		||||
 | 
			
		||||
        const needed = await this.isSyncNeeded(AddonCalendarSyncProvider.SYNC_ID, siteId);
 | 
			
		||||
 | 
			
		||||
        if (needed) {
 | 
			
		||||
            await this.syncEvents(siteId);
 | 
			
		||||
            return this.syncEvents(siteId);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -125,17 +127,12 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
 | 
			
		||||
            updated: false,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let eventIds: number[] = [];
 | 
			
		||||
        try {
 | 
			
		||||
            eventIds = await AddonCalendarOffline.instance.getAllEventsIds(siteId);
 | 
			
		||||
        } catch {
 | 
			
		||||
            // No offline data found.
 | 
			
		||||
        }
 | 
			
		||||
        const eventIds: number[] = await CoreUtils.instance.ignoreErrors(AddonCalendarOffline.instance.getAllEventsIds(siteId), []);
 | 
			
		||||
 | 
			
		||||
        if (eventIds.length > 0) {
 | 
			
		||||
            if (!CoreApp.instance.isOnline()) {
 | 
			
		||||
                // Cannot sync in offline.
 | 
			
		||||
                throw new CoreError('Cannot sync while offline');
 | 
			
		||||
                throw new CoreNetworkError();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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)) {
 | 
			
		||||
            this.logger.debug('Cannot sync event ' + eventId + ' because it is blocked.');
 | 
			
		||||
 | 
			
		||||
            throw Translate.instance.instant(
 | 
			
		||||
            throw new CoreSyncBlockedError(Translate.instance.instant(
 | 
			
		||||
                'core.errorsyncblocked',
 | 
			
		||||
                { $a: Translate.instance.instant('addon.calendar.calendarevent') },
 | 
			
		||||
            );
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // First of all, check if the event has been deleted.
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
    {
 | 
			
		||||
        path: ':courseId/:cmdId',
 | 
			
		||||
        path: ':courseId/:cmId',
 | 
			
		||||
        loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModBookIndexPageModule),
 | 
			
		||||
    },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
            (action)="expandDescription()" iconAction="fas-arrow-right">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <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 *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
    {
 | 
			
		||||
        path: ':courseId/:cmdId',
 | 
			
		||||
        path: ':courseId/:cmId',
 | 
			
		||||
        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> {
 | 
			
		||||
        const siteId = CoreSites.instance.getCurrentSiteId();
 | 
			
		||||
        courseId = courseId || module.course || 1;
 | 
			
		||||
        courseId = courseId || module.course || CoreSites.instance.getCurrentSiteHomeId();
 | 
			
		||||
 | 
			
		||||
        const commonOptions = {
 | 
			
		||||
            readingStrategy: CoreSitesReadingStrategy.OnlyNetwork,
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
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 { CoreCourseActivitySyncBaseProvider } from '@features/course/classes/activity-sync';
 | 
			
		||||
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.
 | 
			
		||||
     * @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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -163,7 +163,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
 | 
			
		||||
     */
 | 
			
		||||
    async syncLessonIfNeeded(
 | 
			
		||||
        lessonId: number,
 | 
			
		||||
        askPassword?: boolean,
 | 
			
		||||
        askPassword = false,
 | 
			
		||||
        siteId?: string,
 | 
			
		||||
    ): Promise<AddonModLessonSyncResult | undefined> {
 | 
			
		||||
        const needed = await this.isSyncNeeded(lessonId, siteId);
 | 
			
		||||
@ -184,8 +184,8 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
 | 
			
		||||
     */
 | 
			
		||||
    async syncLesson(
 | 
			
		||||
        lessonId: number,
 | 
			
		||||
        askPassword?: boolean,
 | 
			
		||||
        ignoreBlock?: boolean,
 | 
			
		||||
        askPassword = false,
 | 
			
		||||
        ignoreBlock = false,
 | 
			
		||||
        siteId?: string,
 | 
			
		||||
    ): Promise<AddonModLessonSyncResult> {
 | 
			
		||||
        siteId = siteId || CoreSites.instance.getCurrentSiteId();
 | 
			
		||||
@ -201,7 +201,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
 | 
			
		||||
        if (!ignoreBlock && CoreSync.instance.isBlocked(AddonModLessonProvider.COMPONENT, lessonId, siteId)) {
 | 
			
		||||
            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);
 | 
			
		||||
@ -222,8 +222,8 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
 | 
			
		||||
     */
 | 
			
		||||
    protected async performSyncLesson(
 | 
			
		||||
        lessonId: number,
 | 
			
		||||
        askPassword?: boolean,
 | 
			
		||||
        ignoreBlock?: boolean,
 | 
			
		||||
        askPassword = false,
 | 
			
		||||
        ignoreBlock = false,
 | 
			
		||||
        siteId?: string,
 | 
			
		||||
    ): Promise<AddonModLessonSyncResult> {
 | 
			
		||||
        // Sync offline logs.
 | 
			
		||||
@ -270,7 +270,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
 | 
			
		||||
    protected async syncAttempts(
 | 
			
		||||
        lessonId: number,
 | 
			
		||||
        result: AddonModLessonSyncResult,
 | 
			
		||||
        askPassword?: boolean,
 | 
			
		||||
        askPassword = false,
 | 
			
		||||
        siteId?: string,
 | 
			
		||||
    ): Promise<AddonModLessonGetPasswordResult | undefined> {
 | 
			
		||||
        let attempts = await AddonModLessonOffline.instance.getLessonAttempts(lessonId, siteId);
 | 
			
		||||
@ -408,8 +408,8 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
 | 
			
		||||
        lessonId: number,
 | 
			
		||||
        result: AddonModLessonSyncResult,
 | 
			
		||||
        passwordData?: AddonModLessonGetPasswordResult,
 | 
			
		||||
        askPassword?: boolean,
 | 
			
		||||
        ignoreBlock?: boolean,
 | 
			
		||||
        askPassword = false,
 | 
			
		||||
        ignoreBlock = false,
 | 
			
		||||
        siteId?: string,
 | 
			
		||||
    ): Promise<void> {
 | 
			
		||||
        // 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 = [
 | 
			
		||||
    {
 | 
			
		||||
        path: ':courseId/:cmdId',
 | 
			
		||||
        path: ':courseId/:cmId',
 | 
			
		||||
        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.
 | 
			
		||||
     * @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();
 | 
			
		||||
 | 
			
		||||
        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.
 | 
			
		||||
     * @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 || []);
 | 
			
		||||
 | 
			
		||||
        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.
 | 
			
		||||
 */
 | 
			
		||||
export class CoreCourseActivitySyncBaseProvider<T> extends CoreSyncBaseProvider<T> {
 | 
			
		||||
export class CoreCourseActivitySyncBaseProvider<T = void> extends CoreSyncBaseProvider<T> {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Conveniece function to prefetch data after an update.
 | 
			
		||||
 | 
			
		||||
@ -112,11 +112,16 @@ export class CoreSyncProvider {
 | 
			
		||||
     * @param siteId Site ID. If not defined, current site.
 | 
			
		||||
     * @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);
 | 
			
		||||
 | 
			
		||||
        data.component = component;
 | 
			
		||||
        data.id = id;
 | 
			
		||||
        data.id = id + '';
 | 
			
		||||
 | 
			
		||||
        await db.insertRecord(SYNC_TABLE_NAME, data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1607,7 +1607,7 @@ export class CoreUtilsProvider {
 | 
			
		||||
            const result = await promise;
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
        } catch {
 | 
			
		||||
            // Ignore errors.
 | 
			
		||||
            return fallback;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user