MOBILE-2873 sync: Sync activities on course prefetch

main
Pau Ferrer Ocaña 2019-03-05 17:09:07 +01:00
parent a26fbeab92
commit 910ee50600
21 changed files with 306 additions and 73 deletions

View File

@ -28,6 +28,7 @@ import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModAssignProvider } from './assign';
import { AddonModAssignHelperProvider } from './helper';
import { AddonModAssignSyncProvider } from './assign-sync';
import { AddonModAssignFeedbackDelegate } from './feedback-delegate';
import { AddonModAssignSubmissionDelegate } from './submission-delegate';
@ -47,7 +48,8 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan
protected textUtils: CoreTextUtilsProvider, protected feedbackDelegate: AddonModAssignFeedbackDelegate,
protected submissionDelegate: AddonModAssignSubmissionDelegate, protected courseHelper: CoreCourseHelperProvider,
protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider,
protected userProvider: CoreUserProvider, protected assignHelper: AddonModAssignHelperProvider) {
protected userProvider: CoreUserProvider, protected assignHelper: AddonModAssignHelperProvider,
protected syncProvider: AddonModAssignSyncProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -454,4 +456,15 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan
return Promise.all(promises);
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
return this.syncProvider.syncAssign(module.instance, siteId);
}
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
@ -22,6 +22,7 @@ import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModChoiceSyncProvider } from './sync';
import { AddonModChoiceProvider } from './choice';
/**
@ -34,10 +35,12 @@ export class AddonModChoicePrefetchHandler extends CoreCourseActivityPrefetchHan
component = AddonModChoiceProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^answers$/;
protected syncProvider: AddonModChoiceSyncProvider; // It will be injected later to prevent circular dependencies.
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected choiceProvider: AddonModChoiceProvider,
protected userProvider: CoreUserProvider) {
protected userProvider: CoreUserProvider, protected injector: Injector) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -133,4 +136,19 @@ export class AddonModChoicePrefetchHandler extends CoreCourseActivityPrefetchHan
invalidateModule(module: any, courseId: number): Promise<any> {
return this.choiceProvider.invalidateChoiceData(courseId);
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
if (!this.syncProvider) {
this.syncProvider = this.injector.get(AddonModChoiceSyncProvider);
}
return this.syncProvider.syncChoice(module.instance, undefined, siteId);
}
}

View File

@ -127,12 +127,13 @@ export class AddonModChoiceSyncProvider extends CoreCourseActivitySyncBaseProvid
* Synchronize a choice.
*
* @param {number} choiceId Choice ID to be synced.
* @param {number} userId User the answers belong to.
* @param {number} [userId] User the answers belong to.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved if sync is successful, rejected otherwise.
*/
syncChoice(choiceId: number, userId: number, siteId?: string): Promise<any> {
syncChoice(choiceId: number, userId?: number, siteId?: string): Promise<any> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
userId = userId || this.sitesProvider.getCurrentSiteUserId();
const syncId = this.getSyncId(choiceId, userId);
if (this.isSyncing(syncId, siteId)) {

View File

@ -27,6 +27,7 @@ import { AddonModDataHelperProvider } from '../../providers/helper';
import { AddonModDataOfflineProvider } from '../../providers/offline';
import { AddonModDataSyncProvider } from '../../providers/sync';
import { AddonModDataComponentsModule } from '../components.module';
import { AddonModDataPrefetchHandler } from '../../providers/prefetch-handler';
/**
* Component that displays a data index page.
@ -82,7 +83,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
constructor(injector: Injector, private dataProvider: AddonModDataProvider, private dataHelper: AddonModDataHelperProvider,
private dataOffline: AddonModDataOfflineProvider, @Optional() content: Content,
private dataSync: AddonModDataSyncProvider, private timeUtils: CoreTimeUtilsProvider,
private prefetchHandler: AddonModDataPrefetchHandler, private timeUtils: CoreTimeUtilsProvider,
private groupsProvider: CoreGroupsProvider, private commentsProvider: CoreCommentsProvider,
private modalCtrl: ModalController, private utils: CoreUtilsProvider, protected navCtrl: NavController,
private ratingOffline: CoreRatingOfflineProvider) {
@ -520,17 +521,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
* @return {Promise<any>} Promise resolved when done.
*/
protected sync(): Promise<any> {
const promises = [
this.dataSync.syncDatabase(this.data.id),
this.dataSync.syncRatings(this.data.coursemodule)
];
return Promise.all(promises).then((results) => {
return results.reduce((a, b) => ({
updated: a.updated || b.updated,
warnings: (a.warnings || []).concat(b.warnings || []),
}), {updated: false});
});
return this.prefetchHandler.sync(this.module);
}
/**

View File

@ -26,6 +26,7 @@ import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreRatingProvider } from '@core/rating/providers/rating';
import { AddonModDataProvider } from './data';
import { AddonModDataSyncProvider } from './sync';
import { AddonModDataHelperProvider } from './helper';
/**
@ -43,7 +44,7 @@ export class AddonModDataPrefetchHandler extends CoreCourseActivityPrefetchHandl
domUtils: CoreDomUtilsProvider, protected dataProvider: AddonModDataProvider,
protected timeUtils: CoreTimeUtilsProvider, protected dataHelper: AddonModDataHelperProvider,
protected groupsProvider: CoreGroupsProvider, protected commentsProvider: CoreCommentsProvider,
private ratingProvider: CoreRatingProvider) {
private ratingProvider: CoreRatingProvider, protected syncProvider: AddonModDataSyncProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -301,4 +302,25 @@ export class AddonModDataPrefetchHandler extends CoreCourseActivityPrefetchHandl
return Promise.all(promises);
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
const promises = [
this.syncProvider.syncDatabase(module.instance, siteId),
this.syncProvider.syncRatings(module.id, true, siteId)
];
return Promise.all(promises).then((results) => {
return results.reduce((a, b) => ({
updated: a.updated || b.updated,
warnings: (a.warnings || []).concat(b.warnings || []),
}), {updated: false});
});
}
}

View File

@ -114,7 +114,7 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
return Promise.all(this.utils.objectToArray(promises));
}));
promises.push(this.syncRatings(undefined, siteId));
promises.push(this.syncRatings(undefined, force, siteId));
return Promise.all(promises);
}
@ -362,13 +362,14 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
* Synchronize offline ratings.
*
* @param {number} [cmId] Course module to be synced. If not defined, sync all databases.
* @param {boolean} [force] Wether to force sync not depending on last execution.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved if sync is successful, rejected otherwise.
*/
syncRatings(cmId?: number, siteId?: string): Promise<any> {
syncRatings(cmId?: number, force?: boolean, siteId?: string): Promise<any> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
return this.ratingSync.syncRatings('mod_data', 'entry', 'module', cmId, 0, siteId).then((results) => {
return this.ratingSync.syncRatings('mod_data', 'entry', 'module', cmId, 0, force, siteId).then((results) => {
let updated = false;
const warnings = [];
const promises = [];

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
@ -25,6 +25,7 @@ import { AddonModFeedbackProvider } from './feedback';
import { AddonModFeedbackHelperProvider } from './helper';
import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreGroupsProvider } from '@providers/groups';
import { AddonModFeedbackSyncProvider } from './sync';
import { CoreUserProvider } from '@core/user/providers/user';
/**
@ -37,11 +38,14 @@ export class AddonModFeedbackPrefetchHandler extends CoreCourseActivityPrefetchH
component = AddonModFeedbackProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^attemptsfinished|^attemptsunfinished$/;
protected syncProvider: AddonModFeedbackSyncProvider; // It will be injected later to prevent circular dependencies.
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected feedbackProvider: AddonModFeedbackProvider,
protected userProvider: CoreUserProvider, protected feedbackHelper: AddonModFeedbackHelperProvider,
protected timeUtils: CoreTimeUtilsProvider, protected groupsProvider: CoreGroupsProvider) {
protected timeUtils: CoreTimeUtilsProvider, protected groupsProvider: CoreGroupsProvider,
protected injector: Injector) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -239,4 +243,19 @@ export class AddonModFeedbackPrefetchHandler extends CoreCourseActivityPrefetchH
});
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
if (!this.syncProvider) {
this.syncProvider = this.injector.get(AddonModFeedbackSyncProvider);
}
return this.syncProvider.syncFeedback(module.instance, siteId);
}
}

View File

@ -376,18 +376,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
* @return {Promise<any>} Promise resolved when done.
*/
protected sync(): Promise<boolean> {
const promises = [];
promises.push(this.forumSync.syncForumDiscussions(this.forum.id));
promises.push(this.forumSync.syncForumReplies(this.forum.id));
promises.push(this.forumSync.syncRatings(this.forum.cmid));
return Promise.all(promises).then((results) => {
return results.reduce((a, b) => ({
updated: a.updated || b.updated,
warnings: (a.warnings || []).concat(b.warnings || []),
}), {updated: false});
});
return this.prefetchHandler.sync(this.module);
}
/**

View File

@ -24,6 +24,7 @@ import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/acti
import { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModForumProvider } from './forum';
import { AddonModForumSyncProvider } from './sync';
import { CoreRatingProvider } from '@core/rating/providers/rating';
/**
@ -46,7 +47,8 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand
private groupsProvider: CoreGroupsProvider,
private userProvider: CoreUserProvider,
private forumProvider: AddonModForumProvider,
private ratingProvider: CoreRatingProvider) {
private ratingProvider: CoreRatingProvider,
private syncProvider: AddonModForumSyncProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -264,4 +266,26 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand
}
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
const promises = [];
promises.push(this.syncProvider.syncForumDiscussions(module.instance, undefined, siteId));
promises.push(this.syncProvider.syncForumReplies(module.instance, undefined, siteId));
promises.push(this.syncProvider.syncRatings(module.id, undefined, true, siteId));
return Promise.all(promises).then((results) => {
return results.reduce((a, b) => ({
updated: a.updated || b.updated,
warnings: (a.warnings || []).concat(b.warnings || []),
}), {updated: false});
});
}
}

View File

@ -23,6 +23,7 @@ import { AddonModGlossaryProvider } from '../../providers/glossary';
import { AddonModGlossaryOfflineProvider } from '../../providers/offline';
import { AddonModGlossarySyncProvider } from '../../providers/sync';
import { AddonModGlossaryModePickerPopoverComponent } from '../mode-picker/mode-picker';
import { AddonModGlossaryPrefetchHandler } from '../../providers/prefetch-handler';
type FetchMode = 'author_all' | 'cat_all' | 'newest_first' | 'recently_updated' | 'search' | 'letter_all';
@ -68,7 +69,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
private popoverCtrl: PopoverController,
private glossaryProvider: AddonModGlossaryProvider,
private glossaryOffline: AddonModGlossaryOfflineProvider,
private glossarySync: AddonModGlossarySyncProvider,
private prefetchHandler: AddonModGlossaryPrefetchHandler,
private ratingOffline: CoreRatingOfflineProvider) {
super(injector);
}
@ -219,17 +220,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
* @return {Promise<any>} Promise resolved when done.
*/
protected sync(): Promise<boolean> {
const promises = [
this.glossarySync.syncGlossaryEntries(this.glossary.id),
this.glossarySync.syncRatings(this.glossary.coursemodule)
];
return Promise.all(promises).then((results) => {
return results.reduce((a, b) => ({
updated: a.updated || b.updated,
warnings: (a.warnings || []).concat(b.warnings || []),
}), {updated: false});
});
return this.prefetchHandler.sync(this.module);
}
/**

View File

@ -24,6 +24,7 @@ import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/acti
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModGlossaryProvider } from './glossary';
import { CoreRatingProvider } from '@core/rating/providers/rating';
import { AddonModGlossarySyncProvider } from './sync';
/**
* Handler to prefetch forums.
@ -44,7 +45,8 @@ export class AddonModGlossaryPrefetchHandler extends CoreCourseActivityPrefetchH
domUtils: CoreDomUtilsProvider,
private userProvider: CoreUserProvider,
private ratingProvider: CoreRatingProvider,
private glossaryProvider: AddonModGlossaryProvider) {
private glossaryProvider: AddonModGlossaryProvider,
private syncProvider: AddonModGlossarySyncProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -187,4 +189,25 @@ export class AddonModGlossaryPrefetchHandler extends CoreCourseActivityPrefetchH
return Promise.all(promises);
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
const promises = [
this.syncProvider.syncGlossaryEntries(module.instance, undefined, siteId),
this.syncProvider.syncRatings(module.id, undefined, siteId)
];
return Promise.all(promises).then((results) => {
return results.reduce((a, b) => ({
updated: a.updated || b.updated,
warnings: (a.warnings || []).concat(b.warnings || []),
}), {updated: false});
});
}
}

View File

@ -118,7 +118,7 @@ export class AddonModGlossarySyncProvider extends CoreSyncBaseProvider {
return Promise.all(this.utils.objectToArray(promises));
}));
promises.push(this.syncRatings(undefined, siteId));
promises.push(this.syncRatings(undefined, force, siteId));
return Promise.all(promises);
}
@ -259,13 +259,14 @@ export class AddonModGlossarySyncProvider extends CoreSyncBaseProvider {
* Synchronize offline ratings.
*
* @param {number} [cmId] Course module to be synced. If not defined, sync all glossaries.
* @param {boolean} [force] Wether to force sync not depending on last execution.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved if sync is successful, rejected otherwise.
*/
syncRatings(cmId?: number, siteId?: string): Promise<any> {
syncRatings(cmId?: number, force?: boolean, siteId?: string): Promise<any> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
return this.ratingSync.syncRatings('mod_glossary', 'entry', 'module', cmId, 0, siteId).then((results) => {
return this.ratingSync.syncRatings('mod_glossary', 'entry', 'module', cmId, 0, force, siteId).then((results) => {
let updated = false;
const warnings = [];
const promises = [];

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { ModalController } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
@ -24,6 +24,7 @@ import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreGroupsProvider } from '@providers/groups';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModLessonProvider } from './lesson';
import { AddonModLessonSyncProvider } from './lesson-sync';
/**
* Handler to prefetch lessons.
@ -36,10 +37,12 @@ export class AddonModLessonPrefetchHandler extends CoreCourseActivityPrefetchHan
// Don't check timers to decrease positives. If a user performs some action it will be reflected in other items.
updatesNames = /^configuration$|^.*files$|^grades$|^gradeitems$|^pages$|^answers$|^questionattempts$|^pagesviewed$/;
protected syncProvider: AddonModLessonSyncProvider; // It will be injected later to prevent circular dependencies.
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected modalCtrl: ModalController, protected groupsProvider: CoreGroupsProvider,
protected lessonProvider: AddonModLessonProvider) {
protected lessonProvider: AddonModLessonProvider, protected injector: Injector) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -429,4 +432,19 @@ export class AddonModLessonPrefetchHandler extends CoreCourseActivityPrefetchHan
});
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
if (!this.syncProvider) {
this.syncProvider = this.injector.get(AddonModLessonSyncProvider);
}
return this.syncProvider.syncLesson(module.instance, false, false, siteId);
}
}

View File

@ -554,4 +554,19 @@ export class AddonModQuizPrefetchHandler extends CoreCourseActivityPrefetchHandl
}
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
if (!this.syncProvider) {
this.syncProvider = this.injector.get(AddonModQuizSyncProvider);
}
return this.syncProvider.syncQuiz(module.instance, false, siteId);
}
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
@ -24,6 +24,7 @@ import { CoreFileProvider } from '@providers/file';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModScormProvider } from './scorm';
import { AddonModScormSyncProvider } from './scorm-sync';
/**
* Progress event used when downloading a SCORM.
@ -58,10 +59,12 @@ export class AddonModScormPrefetchHandler extends CoreCourseActivityPrefetchHand
component = AddonModScormProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^tracks$/;
protected syncProvider: AddonModScormSyncProvider; // It will be injected later to prevent circular dependencies.
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected fileProvider: CoreFileProvider, protected textUtils: CoreTextUtilsProvider,
protected scormProvider: AddonModScormProvider) {
protected scormProvider: AddonModScormProvider, protected injector: Injector) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -423,4 +426,19 @@ export class AddonModScormPrefetchHandler extends CoreCourseActivityPrefetchHand
return Promise.all(promises);
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
if (!this.syncProvider) {
this.syncProvider = this.injector.get(AddonModScormSyncProvider);
}
return this.syncProvider.syncScorm(module.instance, siteId);
}
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
@ -22,6 +22,7 @@ import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModSurveyProvider } from './survey';
import { AddonModSurveySyncProvider } from './sync';
import { AddonModSurveyHelperProvider } from './helper';
/**
@ -34,10 +35,12 @@ export class AddonModSurveyPrefetchHandler extends CoreCourseActivityPrefetchHan
component = AddonModSurveyProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^answers$/;
protected syncProvider: AddonModSurveySyncProvider; // It will be injected later to prevent circular dependencies.
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected surveyProvider: AddonModSurveyProvider,
protected surveyHelper: AddonModSurveyHelperProvider) {
protected surveyHelper: AddonModSurveyHelperProvider, protected injector: Injector) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -126,4 +129,19 @@ export class AddonModSurveyPrefetchHandler extends CoreCourseActivityPrefetchHan
return Promise.all(promises);
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
if (!this.syncProvider) {
this.syncProvider = this.injector.get(AddonModSurveySyncProvider);
}
return this.syncProvider.syncSurvey(module.instance, undefined, siteId);
}
}

View File

@ -130,12 +130,13 @@ export class AddonModSurveySyncProvider extends CoreCourseActivitySyncBaseProvid
* Synchronize a survey.
*
* @param {number} surveyId Survey ID.
* @param {number} userId User the answers belong to.
* @param {number} [userId] User the answers belong to. If not defined, current user.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved if sync is successful, rejected otherwise.
*/
syncSurvey(surveyId: number, userId: number, siteId?: string): Promise<any> {
syncSurvey(surveyId: number, userId?: number, siteId?: string): Promise<any> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
userId = userId || this.sitesProvider.getCurrentSiteUserId();
const syncId = this.getSyncId(surveyId, userId);
if (this.isSyncing(syncId, siteId)) {

View File

@ -27,6 +27,7 @@ import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModWikiProvider } from './wiki';
import { AddonModWikiSyncProvider } from './wiki-sync';
/**
* Handler to prefetch wikis.
@ -42,7 +43,8 @@ export class AddonModWikiPrefetchHandler extends CoreCourseActivityPrefetchHandl
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected wikiProvider: AddonModWikiProvider, protected userProvider: CoreUserProvider,
protected textUtils: CoreTextUtilsProvider, protected courseHelper: CoreCourseHelperProvider,
protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider) {
protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider,
protected syncProvider: AddonModWikiSyncProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -210,4 +212,15 @@ export class AddonModWikiPrefetchHandler extends CoreCourseActivityPrefetchHandl
return Promise.all(promises);
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
return this.syncProvider.syncWiki(module.instance, module.course, module.id, siteId);
}
}

View File

@ -24,6 +24,7 @@ import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/acti
import { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModWorkshopProvider } from './workshop';
import { AddonModWorkshopSyncProvider } from './sync';
import { AddonModWorkshopHelperProvider } from './helper';
/**
@ -47,7 +48,8 @@ export class AddonModWorkshopPrefetchHandler extends CoreCourseActivityPrefetchH
private groupsProvider: CoreGroupsProvider,
private userProvider: CoreUserProvider,
private workshopProvider: AddonModWorkshopProvider,
private workshopHelper: AddonModWorkshopHelperProvider) {
private workshopHelper: AddonModWorkshopHelperProvider,
private syncProvider: AddonModWorkshopSyncProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
@ -365,4 +367,15 @@ export class AddonModWorkshopPrefetchHandler extends CoreCourseActivityPrefetchH
});
});
}
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync(module: any, siteId?: string): Promise<any> {
return this.syncProvider.syncWorkshop(module.instance, siteId);
}
}

View File

@ -294,6 +294,7 @@ export class CoreCourseHelperProvider {
}
return promise.then((sections) => {
// Confirm the download.
return this.confirmDownloadSizeSection(course.id, undefined, sections, true).then(() => {
// User confirmed, get the course handlers if needed.
@ -1317,18 +1318,22 @@ export class CoreCourseHelperProvider {
section.isDownloading = true;
// Validate the section needs to be downloaded and calculate amount of modules that need to be downloaded.
promises.push(this.prefetchDelegate.getModulesStatus(section.modules, courseId, section.id).then((result) => {
if (result.status == CoreConstants.DOWNLOADED || result.status == CoreConstants.NOT_DOWNLOADABLE) {
// Section is downloaded or not downloadable, nothing to do.
return;
}
// Sync the modules first.
promises.push(this.prefetchDelegate.syncModules(section.modules).then(() => {
// Validate the section needs to be downloaded and calculate amount of modules that need to be downloaded.
return this.prefetchDelegate.getModulesStatus(section.modules, courseId, section.id).then((result) => {
if (result.status == CoreConstants.DOWNLOADED || result.status == CoreConstants.NOT_DOWNLOADABLE) {
// Section is downloaded or not downloadable, nothing to do.
return this.prefetchSingleSection(section, result, courseId);
}, (error) => {
section.isDownloading = false;
return ;
}
return Promise.reject(error);
return this.prefetchSingleSection(section, result, courseId);
}, (error) => {
section.isDownloading = false;
return Promise.reject(error);
});
}));
// Download the files in the section description.

View File

@ -206,6 +206,15 @@ export interface CoreCourseModulePrefetchHandler extends CoreDelegateHandler {
* @return {Promise<any>} Promise resolved when done.
*/
removeFiles?(module: any, courseId: number): Promise<any>;
/**
* Sync a module.
*
* @param {any} module Module.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
sync?(module: any, siteId?: any): Promise<any>;
}
/**
@ -1139,12 +1148,42 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate {
// Check if the module has a prefetch handler.
if (handler) {
return handler.prefetch(module, courseId, single);
return this.syncModule(module).then(() => {
return handler.prefetch(module, courseId, single);
});
}
return Promise.resolve();
}
/**
* Sync a group of modules.
*
* @param {any[]} modules Array of modules to sync.
* @return {Promise<any>} Promise resolved when finished.
*/
syncModules(modules: any[]): Promise<any> {
return Promise.all(modules.map((module) => {
return this.syncModule(module);
}));
}
/**
* Sync a module.
*
* @param {any} module Module to sync.
* @return {Promise<any>} Promise resolved when finished.
*/
syncModule(module: any): Promise<any> {
const handler = this.getPrefetchHandlerFor(module);
const promise = handler && handler.sync ? handler.sync(module) : Promise.resolve();
return promise.catch(() => {
// Ignore errors.
});
}
/**
* Prefetches a list of modules using their prefetch handlers.
* If a prefetch already exists for this site and id, returns the current promise.