forked from EVOgeek/Vmeda.Online
		
	MOBILE-3592 user: Implement user sync cron handler
This commit is contained in:
		
							parent
							
								
									3722126b5b
								
							
						
					
					
						commit
						a783a89db3
					
				
							
								
								
									
										307
									
								
								src/core/classes/base-sync.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										307
									
								
								src/core/classes/base-sync.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,307 @@ | |||||||
|  | // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||||
|  | //
 | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||||
|  | // you may not use this file except in compliance with the License.
 | ||||||
|  | // You may obtain a copy of the License at
 | ||||||
|  | //
 | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  | //
 | ||||||
|  | // Unless required by applicable law or agreed to in writing, software
 | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||||
|  | // See the License for the specific language governing permissions and
 | ||||||
|  | // limitations under the License.
 | ||||||
|  | 
 | ||||||
|  | import { CoreApp } from '@services/app'; | ||||||
|  | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreSync } from '@services/sync'; | ||||||
|  | import { CoreTextUtils } from '@services/utils/text'; | ||||||
|  | import { CoreTimeUtils } from '@services/utils/time'; | ||||||
|  | import { Translate } from '@singletons'; | ||||||
|  | import { CoreLogger } from '@singletons/logger'; | ||||||
|  | import { CoreError } from '@classes/errors/error'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Blocked sync error. | ||||||
|  |  */ | ||||||
|  | export class CoreSyncBlockedError extends CoreError {} | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Base class to create sync providers. It provides some common functions. | ||||||
|  |  */ | ||||||
|  | export class CoreSyncBaseProvider<T = void> { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Logger instance. | ||||||
|  |      */ | ||||||
|  |     protected logger: CoreLogger; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Component of the sync provider. | ||||||
|  |      */ | ||||||
|  |     component = 'core'; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Sync provider's interval. | ||||||
|  |      */ | ||||||
|  |     syncInterval = 300000; | ||||||
|  | 
 | ||||||
|  |     // Store sync promises.
 | ||||||
|  |     protected syncPromises: { [siteId: string]: { [uniqueId: string]: Promise<T> } } = {}; | ||||||
|  | 
 | ||||||
|  |     constructor(component: string) { | ||||||
|  |         this.logger = CoreLogger.getInstance(component); | ||||||
|  |         this.component = component; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Add an offline data deleted warning to a list of warnings. | ||||||
|  |      * | ||||||
|  |      * @param warnings List of warnings. | ||||||
|  |      * @param component Component. | ||||||
|  |      * @param name Instance name. | ||||||
|  |      * @param error Specific error message. | ||||||
|  |      */ | ||||||
|  |     protected addOfflineDataDeletedWarning(warnings: string[], component: string, name: string, error: string): void { | ||||||
|  |         const warning = Translate.instance.instant('core.warningofflinedatadeleted', { | ||||||
|  |             component: component, | ||||||
|  |             name: name, | ||||||
|  |             error: error, | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         if (warnings.indexOf(warning) == -1) { | ||||||
|  |             warnings.push(warning); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Add an ongoing sync to the syncPromises list. On finish the promise will be removed. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param promise The promise of the sync to add. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return The sync promise. | ||||||
|  |      */ | ||||||
|  |     async addOngoingSync(id: string | number, promise: Promise<T>, siteId?: string): Promise<T> { | ||||||
|  |         siteId = siteId || CoreSites.instance.getCurrentSiteId(); | ||||||
|  | 
 | ||||||
|  |         if (!siteId) { | ||||||
|  |             throw new CoreError('CoreSyncBaseProvider: Site ID not supplied'); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const uniqueId = this.getUniqueSyncId(id); | ||||||
|  |         if (!this.syncPromises[siteId]) { | ||||||
|  |             this.syncPromises[siteId] = {}; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.syncPromises[siteId][uniqueId] = promise; | ||||||
|  | 
 | ||||||
|  |         // Promise will be deleted when finish.
 | ||||||
|  |         try { | ||||||
|  |             return await promise; | ||||||
|  |         } finally { | ||||||
|  |             delete this.syncPromises[siteId!][uniqueId]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * If there's an ongoing sync for a certain identifier return it. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise of the current sync or undefined if there isn't any. | ||||||
|  |      */ | ||||||
|  |     getOngoingSync(id: string | number, siteId?: string): Promise<T> | undefined { | ||||||
|  |         siteId = siteId || CoreSites.instance.getCurrentSiteId(); | ||||||
|  | 
 | ||||||
|  |         if (!this.isSyncing(id, siteId)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // There's already a sync ongoing for this id, return the promise.
 | ||||||
|  |         const uniqueId = this.getUniqueSyncId(id); | ||||||
|  | 
 | ||||||
|  |         return this.syncPromises[siteId][uniqueId]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the synchronization time in a human readable format. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved with the readable time. | ||||||
|  |      */ | ||||||
|  |     async getReadableSyncTime(id: string | number, siteId?: string): Promise<string> { | ||||||
|  |         const time = await this.getSyncTime(id, siteId); | ||||||
|  | 
 | ||||||
|  |         return this.getReadableTimeFromTimestamp(time); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Given a timestamp return it in a human readable format. | ||||||
|  |      * | ||||||
|  |      * @param timestamp Timestamp | ||||||
|  |      * @return Human readable time. | ||||||
|  |      */ | ||||||
|  |     getReadableTimeFromTimestamp(timestamp: number): string { | ||||||
|  |         if (!timestamp) { | ||||||
|  |             return Translate.instance.instant('core.never'); | ||||||
|  |         } else { | ||||||
|  |             return CoreTimeUtils.instance.userDate(timestamp); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the synchronization time. Returns 0 if no time stored. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved with the time. | ||||||
|  |      */ | ||||||
|  |     async getSyncTime(id: string | number, siteId?: string): Promise<number> { | ||||||
|  |         try { | ||||||
|  |             const entry = await CoreSync.instance.getSyncRecord(this.component, id, siteId); | ||||||
|  | 
 | ||||||
|  |             return entry.time; | ||||||
|  |         } catch { | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the synchronization warnings of an instance. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved with the warnings. | ||||||
|  |      */ | ||||||
|  |     async getSyncWarnings(id: string | number, siteId?: string): Promise<string[]> { | ||||||
|  |         try { | ||||||
|  |             const entry = await CoreSync.instance.getSyncRecord(this.component, id, siteId); | ||||||
|  | 
 | ||||||
|  |             return  <string[]> CoreTextUtils.instance.parseJSON(entry.warnings, []); | ||||||
|  |         } catch { | ||||||
|  |             return []; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Create a unique identifier from component and id. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @return Unique identifier from component and id. | ||||||
|  |      */ | ||||||
|  |     protected getUniqueSyncId(id: string | number): string { | ||||||
|  |         return this.component + '#' + id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if a there's an ongoing syncronization for the given id. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Whether it's synchronizing. | ||||||
|  |      */ | ||||||
|  |     isSyncing(id: string | number, siteId?: string): boolean { | ||||||
|  |         siteId = siteId || CoreSites.instance.getCurrentSiteId(); | ||||||
|  | 
 | ||||||
|  |         const uniqueId = this.getUniqueSyncId(id); | ||||||
|  | 
 | ||||||
|  |         return !!(this.syncPromises[siteId] && this.syncPromises[siteId][uniqueId]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if a sync is needed: if a certain time has passed since the last time. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved with boolean: whether sync is needed. | ||||||
|  |      */ | ||||||
|  |     async isSyncNeeded(id: string | number, siteId?: string): Promise<boolean> { | ||||||
|  |         const time = await this.getSyncTime(id, siteId); | ||||||
|  | 
 | ||||||
|  |         return Date.now() - this.syncInterval >= time; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Set the synchronization time. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @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> { | ||||||
|  |         time = typeof time != 'undefined' ? time : Date.now(); | ||||||
|  | 
 | ||||||
|  |         await CoreSync.instance.insertOrUpdateSyncRecord(this.component, id, { time: time }, siteId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Set the synchronization warnings. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param warnings Warnings to set. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved when done. | ||||||
|  |      */ | ||||||
|  |     async setSyncWarnings(id: string, warnings: string[], siteId?: string): Promise<void> { | ||||||
|  |         const warningsText = JSON.stringify(warnings || []); | ||||||
|  | 
 | ||||||
|  |         await CoreSync.instance.insertOrUpdateSyncRecord(this.component, id, { warnings: warningsText }, siteId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Execute a sync function on selected sites. | ||||||
|  |      * | ||||||
|  |      * @param syncFunctionLog Log message to explain the sync function purpose. | ||||||
|  |      * @param syncFunction Sync function to execute. | ||||||
|  |      * @param siteId Site ID to sync. If not defined, sync all sites. | ||||||
|  |      * @return Resolved with siteIds selected. Rejected if offline. | ||||||
|  |      */ | ||||||
|  |     async syncOnSites(syncFunctionLog: string, syncFunction: (siteId: string) => void, siteId?: string): Promise<void> { | ||||||
|  |         if (!CoreApp.instance.isOnline()) { | ||||||
|  |             const message = `Cannot sync '${syncFunctionLog}' because device is offline.`; | ||||||
|  |             this.logger.debug(message); | ||||||
|  | 
 | ||||||
|  |             throw new CoreError(message); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let siteIds: string[] = []; | ||||||
|  | 
 | ||||||
|  |         if (!siteId) { | ||||||
|  |             // No site ID defined, sync all sites.
 | ||||||
|  |             this.logger.debug(`Try to sync '${syncFunctionLog}' in all sites.`); | ||||||
|  |             siteIds = await CoreSites.instance.getLoggedInSitesIds(); | ||||||
|  |         } else { | ||||||
|  |             this.logger.debug(`Try to sync '${syncFunctionLog}' in site '${siteId}'.`); | ||||||
|  |             siteIds = [siteId]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Execute function for every site.
 | ||||||
|  |         await Promise.all(siteIds.map((siteId) => syncFunction(siteId))); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * If there's an ongoing sync for a certain identifier, wait for it to end. | ||||||
|  |      * If there's no sync ongoing the promise will be resolved right away. | ||||||
|  |      * | ||||||
|  |      * @param id Unique sync identifier per component. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Promise resolved when there's no sync going on for the identifier. | ||||||
|  |      */ | ||||||
|  |     async waitForSync(id: string | number, siteId?: string): Promise<T | undefined> { | ||||||
|  |         const promise = this.getOngoingSync(id, siteId); | ||||||
|  | 
 | ||||||
|  |         if (!promise) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             return await promise; | ||||||
|  |         } catch { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								src/core/features/user/services/handlers/sync-cron.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/core/features/user/services/handlers/sync-cron.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||||
|  | //
 | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||||
|  | // you may not use this file except in compliance with the License.
 | ||||||
|  | // You may obtain a copy of the License at
 | ||||||
|  | //
 | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  | //
 | ||||||
|  | // Unless required by applicable law or agreed to in writing, software
 | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||||
|  | // See the License for the specific language governing permissions and
 | ||||||
|  | // limitations under the License.
 | ||||||
|  | 
 | ||||||
|  | import { Injectable } from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | import { CoreCronHandler } from '@services/cron'; | ||||||
|  | import { CoreUserSync } from '../user-sync'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Synchronization cron handler. | ||||||
|  |  */ | ||||||
|  | @Injectable({ providedIn: 'root' }) | ||||||
|  | export class CoreUserSyncCronHandler implements CoreCronHandler { | ||||||
|  | 
 | ||||||
|  |     name = 'CoreUserSyncCronHandler'; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Execute the process. | ||||||
|  |      * Receives the ID of the site affected, undefined for all sites. | ||||||
|  |      * | ||||||
|  |      * @param siteId ID of the site affected, undefined for all sites. | ||||||
|  |      * @param force Wether the execution is forced (manual sync). | ||||||
|  |      * @return Promise resolved when done, rejected if failure. | ||||||
|  |      */ | ||||||
|  |     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|  |     execute(siteId?: string, force?: boolean): Promise<void> { | ||||||
|  |         return CoreUserSync.instance.syncPreferences(siteId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the time between consecutive executions. | ||||||
|  |      * | ||||||
|  |      * @return Time between consecutive executions (in ms). | ||||||
|  |      */ | ||||||
|  |     getInterval(): number { | ||||||
|  |         return 300000; // 5 minutes.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										107
									
								
								src/core/features/user/services/user-sync.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/core/features/user/services/user-sync.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | |||||||
|  | // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||||
|  | //
 | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||||
|  | // you may not use this file except in compliance with the License.
 | ||||||
|  | // You may obtain a copy of the License at
 | ||||||
|  | //
 | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||||
|  | //
 | ||||||
|  | // Unless required by applicable law or agreed to in writing, software
 | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||||
|  | // See the License for the specific language governing permissions and
 | ||||||
|  | // limitations under the License.
 | ||||||
|  | 
 | ||||||
|  | import { Injectable } from '@angular/core'; | ||||||
|  | 
 | ||||||
|  | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreTextUtils } from '@services/utils/text'; | ||||||
|  | import { CoreUtils } from '@services/utils/utils'; | ||||||
|  | import { CoreSyncBaseProvider } from '@classes/base-sync'; | ||||||
|  | import { makeSingleton } from '@singletons'; | ||||||
|  | import { CoreUserOffline } from './user-offline'; | ||||||
|  | import { CoreUser } from './user'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Service to sync user preferences. | ||||||
|  |  */ | ||||||
|  | @Injectable({ providedIn: 'root' }) | ||||||
|  | export class CoreUserSyncProvider extends CoreSyncBaseProvider<string[]> { | ||||||
|  | 
 | ||||||
|  |     static readonly AUTO_SYNCED = 'core_user_autom_synced'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super('CoreUserSync'); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Try to synchronize user preferences in a certain site or in all sites. | ||||||
|  |      * | ||||||
|  |      * @param siteId Site ID to sync. If not defined, sync all sites. | ||||||
|  |      * @return Promise resolved with warnings if sync is successful, rejected if sync fails. | ||||||
|  |      */ | ||||||
|  |     syncPreferences(siteId?: string): Promise<void> { | ||||||
|  |         return this.syncOnSites('all user preferences', this.syncSitePreferences.bind(this), siteId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Sync user preferences of a site. | ||||||
|  |      * | ||||||
|  |      * @param siteId Site ID to sync. | ||||||
|  |      * @param Promise resolved with warnings if sync is successful, rejected if sync fails. | ||||||
|  |      */ | ||||||
|  |     async syncSitePreferences(siteId: string): Promise<string[]> { | ||||||
|  |         siteId = siteId || CoreSites.instance.getCurrentSiteId(); | ||||||
|  | 
 | ||||||
|  |         const syncId = 'preferences'; | ||||||
|  | 
 | ||||||
|  |         if (this.isSyncing(syncId, siteId)) { | ||||||
|  |             // There's already a sync ongoing, return the promise.
 | ||||||
|  |             return this.getOngoingSync(syncId, siteId)!; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.logger.debug('Try to sync user preferences'); | ||||||
|  | 
 | ||||||
|  |         const syncPromise = this.performSyncSitePreferences(siteId); | ||||||
|  | 
 | ||||||
|  |         return this.addOngoingSync(syncId, syncPromise, siteId); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Sync user preferences of a site. | ||||||
|  |      * | ||||||
|  |      * @param siteId Site ID to sync. | ||||||
|  |      * @param Promise resolved if sync is successful, rejected if sync fails. | ||||||
|  |      */ | ||||||
|  |     protected async performSyncSitePreferences(siteId: string): Promise<string[]> { | ||||||
|  |         const warnings: string[] = []; | ||||||
|  | 
 | ||||||
|  |         const preferences = await CoreUserOffline.instance.getChangedPreferences(siteId); | ||||||
|  | 
 | ||||||
|  |         await CoreUtils.instance.allPromises(preferences.map(async (preference) => { | ||||||
|  |             const onlineValue = await CoreUser.instance.getUserPreferenceOnline(preference.name, siteId); | ||||||
|  | 
 | ||||||
|  |             if (onlineValue !== null && preference.onlinevalue != onlineValue) { | ||||||
|  |                 // Preference was changed on web while the app was offline, do not sync.
 | ||||||
|  |                 return CoreUserOffline.instance.setPreference(preference.name, onlineValue, onlineValue, siteId); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             try { | ||||||
|  |                 await CoreUser.instance.setUserPreference(preference.name, preference.value, siteId); | ||||||
|  |             } catch (error) { | ||||||
|  |                 if (CoreUtils.instance.isWebServiceError(error)) { | ||||||
|  |                     warnings.push(CoreTextUtils.instance.getErrorMessageFromError(error)!); | ||||||
|  |                 } else { | ||||||
|  |                     // Couldn't connect to server, reject.
 | ||||||
|  |                     throw error; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         })); | ||||||
|  | 
 | ||||||
|  |         // All done, return the warnings.
 | ||||||
|  |         return warnings; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class CoreUserSync extends makeSingleton(CoreUserSyncProvider) {} | ||||||
| @ -41,6 +41,13 @@ const routes: Routes = [ | |||||||
|             ], |             ], | ||||||
|             multi: true, |             multi: true, | ||||||
|         }, |         }, | ||||||
|  |         // { @todo: Uncomment when the init process has been fixed.
 | ||||||
|  |         //     provide: APP_INITIALIZER,
 | ||||||
|  |         //     multi: true,
 | ||||||
|  |         //     deps: [CoreCronDelegate, CoreUserSyncCronHandler],
 | ||||||
|  |         //     useFactory: (cronDelegate: CoreCronDelegate, syncHandler: CoreUserSyncCronHandler) =>
 | ||||||
|  |         //         () => cronDelegate.register(syncHandler),
 | ||||||
|  |         // },
 | ||||||
|     ], |     ], | ||||||
| }) | }) | ||||||
| export class CoreUserModule {} | export class CoreUserModule {} | ||||||
|  | |||||||
| @ -112,7 +112,7 @@ 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: CoreSyncRecord, siteId?: string): Promise<void> { |     async insertOrUpdateSyncRecord(component: string, id: string, 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; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user