diff --git a/src/addon/mod/assign/components/submission/submission.ts b/src/addon/mod/assign/components/submission/submission.ts index cffefe88d..d50a97a63 100644 --- a/src/addon/mod/assign/components/submission/submission.ts +++ b/src/addon/mod/assign/components/submission/submission.ts @@ -408,7 +408,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy { return Promise.all(promises); }).then(() => { // Get submission status. - return this.assignProvider.getSubmissionStatus(this.assign.id, this.submitId, isBlind); + return this.assignProvider.getSubmissionStatusWithRetry(this.assign, this.submitId, isBlind); }).then((response) => { const promises = []; diff --git a/src/addon/mod/assign/providers/assign.ts b/src/addon/mod/assign/providers/assign.ts index c6c3bf8cf..33d3f0652 100644 --- a/src/addon/mod/assign/providers/assign.ts +++ b/src/addon/mod/assign/providers/assign.ts @@ -503,6 +503,33 @@ export class AddonModAssignProvider { }); } + /** + * Get information about an assignment submission status for a given user. + * If the data doesn't include the user submission, retry ignoring cache. + * + * @param {any} assign Assignment. + * @param {number} [userId] User id (empty for current user). + * @param {boolean} [isBlind] If blind marking is enabled or not. + * @param {number} [filter=true] True to filter WS response and rewrite URLs, false otherwise. + * @param {boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down). + * @param {string} [siteId] Site id (empty for current site). + * @return {Promise} Promise always resolved with the user submission status. + */ + getSubmissionStatusWithRetry(assign: any, userId?: number, isBlind?: boolean, filter: boolean = true, ignoreCache?: boolean, + siteId?: string): Promise { + + return this.getSubmissionStatus(assign.id, userId, isBlind, filter, ignoreCache, siteId).then((response) => { + const userSubmission = this.getSubmissionObjectFromAttempt(assign, response.lastattempt); + + if (!userSubmission) { + // Try again, ignoring cache. + return this.getSubmissionStatus(assign.id, userId, isBlind, filter, true, siteId); + } + + return response; + }); + } + /** * Get cache key for get submission status data WS calls. * diff --git a/src/addon/mod/assign/providers/prefetch-handler.ts b/src/addon/mod/assign/providers/prefetch-handler.ts index 93ecb3f68..a83d6c240 100644 --- a/src/addon/mod/assign/providers/prefetch-handler.ts +++ b/src/addon/mod/assign/providers/prefetch-handler.ts @@ -156,7 +156,8 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan protected getSubmissionFiles(assign: any, submitId: number, blindMarking: boolean, siteId?: string) : Promise { - return this.assignProvider.getSubmissionStatus(assign.id, submitId, blindMarking, true, false, siteId).then((response) => { + return this.assignProvider.getSubmissionStatusWithRetry(assign, submitId, blindMarking, true, true, siteId) + .then((response) => { const promises = []; if (response.lastattempt) { @@ -200,6 +201,17 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan return this.assignProvider.invalidateContent(moduleId, courseId); } + /** + * Invalidate WS calls needed to determine module status. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @return {Promise} Promise resolved when invalidated. + */ + invalidateModule(module: any, courseId: number): Promise { + return this.assignProvider.invalidateAssignmentData(courseId); + } + /** * Whether or not the handler is enabled on a site level. * @@ -252,10 +264,11 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan subPromises.push(this.courseHelper.getModuleCourseIdByInstance(assign.id, 'assign', siteId)); - // Get all files and fetch them. - subPromises.push(this.getFiles(module, courseId, single, siteId).then((files) => { - return this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id); - })); + // Download intro files and attachments. Do not call getFiles because it'd call some WS twice. + let files = assign.introattachments || []; + files = files.concat(this.getIntroFilesFromInstance(module, assign)); + + subPromises.push(this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id)); return Promise.all(subPromises); })); @@ -288,8 +301,8 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan const subPromises = []; submissions.forEach((submission) => { - subPromises.push(this.assignProvider.getSubmissionStatus(assign.id, submission.submitid, - !!submission.blindid, true, false, siteId).then((subm) => { + subPromises.push(this.assignProvider.getSubmissionStatusWithRetry(assign, submission.submitid, + !!submission.blindid, true, true, siteId).then((subm) => { return this.prefetchSubmission(assign, courseId, moduleId, subm, submission.submitid, siteId); }).catch((error) => { if (error && error.errorcode == 'nopermission') { @@ -308,7 +321,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan // Prefetch the submission of the current user even if it does not exist, this will be create it. if (!data.submissions || !data.submissions.find((subm) => subm.submitid == userId)) { - subPromises.push(this.assignProvider.getSubmissionStatus(assign.id, userId, false, true, false, siteId) + subPromises.push(this.assignProvider.getSubmissionStatusWithRetry(assign, userId, false, true, true, siteId) .then((subm) => { return this.prefetchSubmission(assign, courseId, moduleId, subm, userId, siteId); })); @@ -330,7 +343,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan } else { // Student. promises.push( - this.assignProvider.getSubmissionStatus(assign.id, userId, false, true, false, siteId).then((subm) => { + this.assignProvider.getSubmissionStatusWithRetry(assign, userId, false, true, true, siteId).then((subm) => { return this.prefetchSubmission(assign, courseId, moduleId, subm, userId, siteId); }).catch((error) => { // Ignore if the user can't view their own submission. @@ -378,7 +391,16 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan // Prefetch submission plugins data. if (userSubmission.plugins) { userSubmission.plugins.forEach((plugin) => { + // Prefetch the plugin WS data. promises.push(this.submissionDelegate.prefetch(assign, userSubmission, plugin, siteId)); + + // Prefetch the plugin files. + promises.push(this.submissionDelegate.getPluginFiles(assign, userSubmission, plugin, siteId) + .then((files) => { + return this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id); + }).catch(() => { + // Ignore errors. + })); }); } @@ -403,7 +425,15 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan // Prefetch feedback plugins data. if (submission.feedback.plugins) { submission.feedback.plugins.forEach((plugin) => { + // Prefetch the plugin WS data. promises.push(this.feedbackDelegate.prefetch(assign, submission, plugin, siteId)); + + // Prefetch the plugin files. + promises.push(this.feedbackDelegate.getPluginFiles(assign, submission, plugin, siteId).then((files) => { + return this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id); + }).catch(() => { + // Ignore errors. + })); }); } }