Merge pull request #1590 from crazyserver/MOBILE-2669

Mobile 2669
main
Juan Leyva 2018-11-09 13:37:55 +01:00 committed by GitHub
commit 7150cd12b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 131 additions and 79 deletions

View File

@ -75,7 +75,7 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
this.loadContent(false, true).then(() => { this.loadContent(false, true).then(() => {
this.assignProvider.logView(this.assign.id).then(() => { this.assignProvider.logView(this.assign.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });
@ -104,7 +104,7 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
this.submittedObserver = this.eventsProvider.on(AddonModAssignProvider.SUBMITTED_FOR_GRADING_EVENT, (data) => { this.submittedObserver = this.eventsProvider.on(AddonModAssignProvider.SUBMITTED_FOR_GRADING_EVENT, (data) => {
if (this.assign && data.assignmentId == this.assign.id && data.userId == this.userId) { if (this.assign && data.assignmentId == this.assign.id && data.userId == this.userId) {
// Assignment submitted, check completion. // Assignment submitted, check completion.
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
// Reload data since it can have offline data now. // Reload data since it can have offline data now.
this.showLoadingAndRefresh(true, false); this.showLoadingAndRefresh(true, false);

View File

@ -166,7 +166,7 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
this.bookProvider.logView(this.module.instance, chapterId).then(() => { this.bookProvider.logView(this.module.instance, chapterId).then(() => {
// Module is completed when last chapter is viewed, so we only check completion if the last is reached. // Module is completed when last chapter is viewed, so we only check completion if the last is reached.
if (!this.nextChapter) { if (!this.nextChapter) {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
} }
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.

View File

@ -48,7 +48,7 @@ export class AddonModChatIndexComponent extends CoreCourseModuleMainActivityComp
this.loadContent().then(() => { this.loadContent().then(() => {
this.chatProvider.logView(this.chat.id).then(() => { this.chatProvider.logView(this.chat.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -67,7 +67,7 @@ export class AddonModChoiceIndexComponent extends CoreCourseModuleMainActivityCo
return; return;
} }
this.choiceProvider.logView(this.choice.id).then(() => { this.choiceProvider.logView(this.choice.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch((error) => { }).catch((error) => {
// Ignore errors. // Ignore errors.
}); });
@ -354,7 +354,7 @@ export class AddonModChoiceIndexComponent extends CoreCourseModuleMainActivityCo
this.choiceProvider.submitResponse(this.choice.id, this.choice.name, this.courseId, responses).then(() => { this.choiceProvider.submitResponse(this.choice.id, this.choice.name, this.courseId, responses).then(() => {
// Success! // Success!
// Check completion since it could be configured to complete once the user answers the choice. // Check completion since it could be configured to complete once the user answers the choice.
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
this.domUtils.scrollToTop(this.content); this.domUtils.scrollToTop(this.content);
// Let's refresh the data. // Let's refresh the data.

View File

@ -104,7 +104,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
} }
this.dataProvider.logView(this.data.id).then(() => { this.dataProvider.logView(this.data.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -95,7 +95,7 @@ export class AddonModFeedbackFormPage implements OnDestroy {
ionViewDidLoad(): void { ionViewDidLoad(): void {
this.fetchData().then(() => { this.fetchData().then(() => {
this.feedbackProvider.logView(this.feedback.id, true).then(() => { this.feedbackProvider.logView(this.feedback.id, true).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -56,7 +56,7 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
} else { } else {
this.loadContent().then(() => { this.loadContent().then(() => {
this.folderProvider.logView(this.module.instance).then(() => { this.folderProvider.logView(this.module.instance).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -114,7 +114,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
} }
this.forumProvider.logView(this.forum.id).then(() => { this.forumProvider.logView(this.forum.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch((error) => { }).catch((error) => {
// Ignore errors. // Ignore errors.
}); });
@ -423,7 +423,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
}); });
// Check completion since it could be configured to complete once the user adds a new discussion or replies. // Check completion since it could be configured to complete once the user adds a new discussion or replies.
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
} }
} }

View File

@ -77,7 +77,13 @@ export class AddonModForumModuleHandler implements CoreCourseModuleHandler {
} }
}; };
this.updateExtraBadge(data, courseId, module.id); if (typeof module.afterlink != 'undefined') {
data.extraBadgeColor = '';
const match = />(\d+)[^<]+/.exec(module.afterlink);
data.extraBadge = match ? this.translate.instant('addon.mod_forum.unreadpostsnumber', {$a : match[1] }) : '';
} else {
this.updateExtraBadge(data, courseId, module.id);
}
const event = this.eventsProvider.on(AddonModForumProvider.MARK_READ_EVENT, (eventData) => { const event = this.eventsProvider.on(AddonModForumProvider.MARK_READ_EVENT, (eventData) => {
if (eventData.courseId == courseId && eventData.moduleId == module.id) { if (eventData.courseId == courseId && eventData.moduleId == module.id) {

View File

@ -86,7 +86,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
} }
this.glossaryProvider.logView(this.glossary.id, this.viewMode).then(() => { this.glossaryProvider.logView(this.glossary.id, this.viewMode).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch((error) => { }).catch((error) => {
// Ignore errors. // Ignore errors.
}); });
@ -387,7 +387,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
this.showLoadingAndRefresh(false); this.showLoadingAndRefresh(false);
// Check completion since it could be configured to complete once the user adds a new discussion or replies. // Check completion since it could be configured to complete once the user adds a new discussion or replies.
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
} }
} }

View File

@ -53,7 +53,7 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
this.loadContent().then(() => { this.loadContent().then(() => {
this.imscpProvider.logView(this.module.instance).then(() => { this.imscpProvider.logView(this.module.instance).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -310,7 +310,7 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
*/ */
protected logView(): void { protected logView(): void {
this.lessonProvider.logViewLesson(this.lesson.id, this.password).then(() => { this.lessonProvider.logViewLesson(this.lesson.id, this.password).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch((error) => { }).catch((error) => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -51,7 +51,7 @@ export class AddonModLtiIndexComponent extends CoreCourseModuleMainActivityCompo
* Check the completion. * Check the completion.
*/ */
protected checkCompletion(): void { protected checkCompletion(): void {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
} }
/** /**

View File

@ -88,7 +88,7 @@ export class AddonModLtiModuleHandler implements CoreCourseModuleHandler {
return this.ltiProvider.getLtiLaunchData(ltiData.id).then((launchData) => { return this.ltiProvider.getLtiLaunchData(ltiData.id).then((launchData) => {
// "View" LTI. // "View" LTI.
this.ltiProvider.logView(ltiData.id).then(() => { this.ltiProvider.logView(ltiData.id).then(() => {
this.courseProvider.checkModuleCompletion(courseId, module.completionstatus); this.courseProvider.checkModuleCompletion(courseId, module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -54,7 +54,7 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp
this.loadContent().then(() => { this.loadContent().then(() => {
this.pageProvider.logView(this.module.instance).then(() => { this.pageProvider.logView(this.module.instance).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -86,7 +86,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
} }
this.quizProvider.logViewQuiz(this.quizData.id).then(() => { this.quizProvider.logViewQuiz(this.quizData.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch((error) => { }).catch((error) => {
// Ignore errors. // Ignore errors.
}); });
@ -370,7 +370,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
*/ */
protected goToAutoReview(): Promise<any> { protected goToAutoReview(): Promise<any> {
// If we go to auto review it means an attempt was finished. Check completion status. // If we go to auto review it means an attempt was finished. Check completion status.
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
// Verify that user can see the review. // Verify that user can see the review.
const attemptId = this.autoReview.attemptId; const attemptId = this.autoReview.attemptId;
@ -395,7 +395,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
protected hasSyncSucceed(result: any): boolean { protected hasSyncSucceed(result: any): boolean {
if (result.attemptFinished) { if (result.attemptFinished) {
// An attempt was finished, check completion status. // An attempt was finished, check completion status.
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
} }
// If the sync call isn't rejected it means the sync was successful. // If the sync call isn't rejected it means the sync was successful.
@ -484,7 +484,7 @@ export class AddonModQuizIndexComponent extends CoreCourseModuleMainActivityComp
protected isRefreshSyncNeeded(syncEventData: any): boolean { protected isRefreshSyncNeeded(syncEventData: any): boolean {
if (syncEventData.attemptFinished) { if (syncEventData.attemptFinished) {
// An attempt was finished, check completion status. // An attempt was finished, check completion status.
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
} }
if (this.quizData && syncEventData.quizId == this.quizData.id) { if (this.quizData && syncEventData.quizId == this.quizData.id) {

View File

@ -51,7 +51,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
this.loadContent().then(() => { this.loadContent().then(() => {
this.resourceProvider.logView(this.module.instance).then(() => { this.resourceProvider.logView(this.module.instance).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -153,7 +153,7 @@ export class AddonModResourceHelperProvider {
return this.courseHelper.downloadModuleAndOpenFile(module, courseId, AddonModResourceProvider.COMPONENT, module.id, return this.courseHelper.downloadModuleAndOpenFile(module, courseId, AddonModResourceProvider.COMPONENT, module.id,
module.contents).then(() => { module.contents).then(() => {
this.resourceProvider.logView(module.instance).then(() => { this.resourceProvider.logView(module.instance).then(() => {
this.courseProvider.checkModuleCompletion(courseId, module.completionstatus); this.courseProvider.checkModuleCompletion(courseId, module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -134,27 +134,30 @@ export class AddonModResourceModuleHandler implements CoreCourseModuleHandler {
*/ */
protected getResourceData(module: any, courseId: number, handlerData: CoreCourseModuleHandlerData): Promise<any> { protected getResourceData(module: any, courseId: number, handlerData: CoreCourseModuleHandlerData): Promise<any> {
const promises = []; const promises = [];
let resourceInfo; let infoFiles = [],
options: any = {};
// Check if the button needs to be shown or not. This also loads the module contents. // Check if the button needs to be shown or not. This also loads the module contents.
promises.push(this.hideOpenButton(module, courseId).then((hideOpenButton) => { promises.push(this.hideOpenButton(module, courseId).then((hideOpenButton) => {
handlerData.buttons[0].hidden = hideOpenButton; handlerData.buttons[0].hidden = hideOpenButton;
})); }));
if (this.resourceProvider.isGetResourceWSAvailable()) { if (typeof module.customdata != 'undefined') {
options = this.textUtils.unserialize(this.textUtils.parseJSON(module.customdata));
} else if (this.resourceProvider.isGetResourceWSAvailable()) {
// Get the resource data. // Get the resource data.
promises.push(this.resourceProvider.getResourceData(courseId, module.id).then((info) => { promises.push(this.resourceProvider.getResourceData(courseId, module.id).then((info) => {
resourceInfo = info; infoFiles = info.contentfiles;
options = this.textUtils.unserialize(info.displayoptions);
})); }));
} }
return Promise.all(promises).then(() => { return Promise.all(promises).then(() => {
const files = module.contents && module.contents.length ? module.contents : resourceInfo && resourceInfo.contentfiles, const files = module.contents && module.contents.length ? module.contents : infoFiles,
resourceData = { resourceData = {
icon: '', icon: '',
extra: '' extra: ''
}, },
options = (resourceInfo && this.textUtils.unserialize(resourceInfo.displayoptions)) || {},
extra = []; extra = [];
if (files && files.length) { if (files && files.length) {
@ -162,19 +165,32 @@ export class AddonModResourceModuleHandler implements CoreCourseModuleHandler {
resourceData.icon = this.mimetypeUtils.getFileIcon(file.filename); resourceData.icon = this.mimetypeUtils.getFileIcon(file.filename);
if (options.showsize) { if (options.showsize) {
const size = files.reduce((result, file) => { let size;
return result + file.filesize; if (options.filedetails) {
}, 0); size = options.filedetails.size;
} else {
size = files.reduce((result, file) => {
return result + file.filesize;
}, 0);
}
extra.push(this.textUtils.bytesToSize(size, 1)); extra.push(this.textUtils.bytesToSize(size, 1));
} }
if (options.showtype) { if (options.showtype) {
// We should take it from options.filedetails.size if avalaible ∫but it's already translated.
extra.push(this.mimetypeUtils.getMimetypeDescription(file)); extra.push(this.mimetypeUtils.getMimetypeDescription(file));
} }
if (options.showdate) { if (options.showdate) {
/* Modified date may be up to several minutes later than uploaded date just because if (options.filedetails && options.filedetails.modifieddate) {
teacher did not submit the form promptly. Give teacher up to 5 minutes to do it. */ extra.push(this.translate.instant('addon.mod_resource.modifieddate',
if (file.timemodified > file.timecreated + CoreConstants.SECONDS_MINUTE * 5) { {$a: moment(options.filedetails.modifieddate * 1000).format('LLL')}));
} else if (options.filedetails && options.filedetails.uploadeddate) {
extra.push(this.translate.instant('addon.mod_resource.uploadeddate',
{$a: moment(options.filedetails.uploadeddate * 1000).format('LLL')}));
} else if (file.timemodified > file.timecreated + CoreConstants.SECONDS_MINUTE * 5) {
/* Modified date may be up to several minutes later than uploaded date just because
teacher did not submit the form promptly. Give teacher up to 5 minutes to do it. */
extra.push(this.translate.instant('addon.mod_resource.modifieddate', extra.push(this.translate.instant('addon.mod_resource.modifieddate',
{$a: moment(file.timemodified * 1000).format('LLL')})); {$a: moment(file.timemodified * 1000).format('LLL')}));
} else { } else {

View File

@ -94,7 +94,7 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
* Check the completion. * Check the completion.
*/ */
protected checkCompletion(): void { protected checkCompletion(): void {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
} }
/** /**

View File

@ -54,7 +54,7 @@ export class AddonModSurveyIndexComponent extends CoreCourseModuleMainActivityCo
this.loadContent(false, true).then(() => { this.loadContent(false, true).then(() => {
this.surveyProvider.logView(this.survey.id).then(() => { this.surveyProvider.logView(this.survey.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -172,7 +172,7 @@ export class AddonModUrlIndexComponent extends CoreCourseModuleMainResourceCompo
*/ */
go(): void { go(): void {
this.urlProvider.logView(this.module.instance).then(() => { this.urlProvider.logView(this.module.instance).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -166,7 +166,7 @@ export class AddonModUrlModuleHandler implements CoreCourseModuleHandler {
*/ */
protected openUrl(module: any, courseId: number): void { protected openUrl(module: any, courseId: number): void {
this.urlProvider.logView(module.instance).then(() => { this.urlProvider.logView(module.instance).then(() => {
this.courseProvider.checkModuleCompletion(courseId, module.completionstatus); this.courseProvider.checkModuleCompletion(courseId, module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -105,7 +105,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
if (this.isMainPage) { if (this.isMainPage) {
this.wikiProvider.logView(this.wiki.id).then(() => { this.wikiProvider.logView(this.wiki.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch((error) => { }).catch((error) => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -106,7 +106,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
} }
this.workshopProvider.logView(this.workshop.id).then(() => { this.workshopProvider.logView(this.workshop.id).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch((error) => { }).catch((error) => {
// Ignore errors. // Ignore errors.
}); });
@ -123,7 +123,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
this.showLoadingAndRefresh(true); this.showLoadingAndRefresh(true);
// Check completion since it could be configured to complete once the user adds a new discussion or replies. // Check completion since it could be configured to complete once the user adds a new discussion or replies.
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
} }
} }

View File

@ -131,7 +131,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
this.fetchSubmissionData().then(() => { this.fetchSubmissionData().then(() => {
this.workshopProvider.logViewSubmission(this.submissionId).then(() => { this.workshopProvider.logViewSubmission(this.submissionId).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -25,7 +25,7 @@ import { CoreCourseProvider } from '../../providers/course';
* *
* Example usage: * Example usage:
* *
* <core-course-module-completion [completion]="module.completionstatus" [moduleName]="module.name" * <core-course-module-completion [completion]="module.completiondata" [moduleName]="module.name"
* (completionChanged)="completionChanged()"></core-course-module-completion> * (completionChanged)="completionChanged()"></core-course-module-completion>
*/ */
@Component({ @Component({

View File

@ -5,9 +5,9 @@
<core-format-text [text]="module.handlerData.title"></core-format-text> <core-format-text [text]="module.handlerData.title"></core-format-text>
<!-- Buttons. --> <!-- Buttons. -->
<div item-end *ngIf="module.uservisible !== false" class="buttons core-module-buttons" [ngClass]="{'core-button-completion': module.completionstatus}"> <div item-end *ngIf="module.uservisible !== false" class="buttons core-module-buttons" [ngClass]="{'core-button-completion': module.completiondata}">
<!-- Module completion. --> <!-- Module completion. -->
<core-course-module-completion *ngIf="module.completionstatus" [completion]="module.completionstatus" [moduleName]="module.name" (completionChanged)="completionChanged.emit()"></core-course-module-completion> <core-course-module-completion *ngIf="module.completiondata" [completion]="module.completiondata" [moduleName]="module.name" (completionChanged)="completionChanged.emit()"></core-course-module-completion>
<div class="core-module-buttons-more"> <div class="core-module-buttons-more">
<!-- Download button. --> <!-- Download button. -->
@ -37,7 +37,7 @@
<ion-badge item-end *ngIf="module.visible === 0 && (!section || section.visible)" text-wrap>{{ 'core.course.hiddenfromstudents' | translate }}</ion-badge> <ion-badge item-end *ngIf="module.visible === 0 && (!section || section.visible)" text-wrap>{{ 'core.course.hiddenfromstudents' | translate }}</ion-badge>
<ion-badge item-end *ngIf="module.visible !== 0 && module.isStealth" text-wrap>{{ 'core.course.hiddenoncoursepage' | translate }}</ion-badge> <ion-badge item-end *ngIf="module.visible !== 0 && module.isStealth" text-wrap>{{ 'core.course.hiddenoncoursepage' | translate }}</ion-badge>
<ion-badge item-end *ngIf="module.availabilityinfo" text-wrap><core-format-text [text]="module.availabilityinfo"></core-format-text></ion-badge> <ion-badge item-end *ngIf="module.availabilityinfo" text-wrap><core-format-text [text]="module.availabilityinfo"></core-format-text></ion-badge>
<ion-badge item-end *ngIf="module.completionstatus && module.completionstatus.offline" color="warning" text-wrap>{{ 'core.course.manualcompletionnotsynced' | translate }}</ion-badge> <ion-badge item-end *ngIf="module.completiondata && module.completiondata.offline" color="warning" text-wrap>{{ 'core.course.manualcompletionnotsynced' | translate }}</ion-badge>
</div> </div>
<core-format-text class="core-module-description" *ngIf="module.description" maxHeight="80" [text]="module.description"></core-format-text> <core-format-text class="core-module-description" *ngIf="module.description" maxHeight="80" [text]="module.description"></core-format-text>
</a> </a>

View File

@ -184,34 +184,41 @@ export class CoreCourseSectionPage implements OnDestroy {
} }
}).then(() => { }).then(() => {
const promises = []; const promises = [];
let promise;
// Get the completion status. // Get all the sections.
if (this.course.enablecompletion === false) { promises.push(this.courseProvider.getSections(this.course.id, false, true).then((sections) => {
// Completion not enabled. if (refresh) {
promise = Promise.resolve({}); // Invalidate the recently downloaded module list. To ensure info can be prefetched.
} else { const modules = this.courseProvider.getSectionsModules(sections);
promise = this.courseProvider.getActivitiesCompletionStatus(this.course.id).catch(() => {
// It failed, don't use completion.
return {};
});
}
promises.push(promise.then((completionStatus) => { return this.prefetchDelegate.invalidateModules(modules, this.course.id).then(() => {
// Get all the sections.
return this.courseProvider.getSections(this.course.id, false, true).then((sections) => {
if (refresh) {
// Invalidate the recently downloaded module list. To ensure info can be prefetched.
const modules = this.courseProvider.getSectionsModules(sections);
return this.prefetchDelegate.invalidateModules(modules, this.course.id).then(() => {
return sections;
});
} else {
return sections; return sections;
} });
}).then((sections) => { } else {
return sections;
}
}).then((sections) => {
let promise;
// Get the completion status.
if (this.course.enablecompletion === false) {
// Completion not enabled.
promise = Promise.resolve({});
} else {
const sectionWithModules = sections.find((section) => {
return section.modules.length > 0;
});
if (sectionWithModules && typeof sectionWithModules.modules[0].completion != 'undefined') {
promise = Promise.resolve({});
} else {
promise = this.courseProvider.getActivitiesCompletionStatus(this.course.id).catch(() => {
// It failed, don't use completion.
return {};
});
}
}
return promise.then((completionStatus) => {
this.courseHelper.addHandlerDataForModules(sections, this.course.id, completionStatus, this.course.fullname); this.courseHelper.addHandlerDataForModules(sections, this.course.id, completionStatus, this.course.fullname);
// Format the name of each section and check if it has content. // Format the name of each section and check if it has content.

View File

@ -147,11 +147,22 @@ export class CoreCourseHelperProvider {
section.modules.forEach((module) => { section.modules.forEach((module) => {
module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, section.id); module.handlerData = this.moduleDelegate.getModuleDataFor(module.modname, module, courseId, section.id);
if (completionStatus && typeof completionStatus[module.id] != 'undefined') { if (module.completiondata && module.completion > 0) {
// Check if activity has completions and if it's marked. module.completiondata.courseId = courseId;
module.completionstatus = completionStatus[module.id]; module.completiondata.courseName = courseName;
module.completionstatus.courseId = courseId; module.completiondata.tracking = module.completion;
module.completionstatus.courseName = courseName; module.completiondata.cmid = module.id;
// Use of completionstatus is deprecated, use completiondata instead.
module.completionstatus = module.completiondata;
} else if (completionStatus && typeof completionStatus[module.id] != 'undefined') {
// Should not happen on > 3.6. Check if activity has completions and if it's marked.
module.completiondata = completionStatus[module.id];
module.completiondata.courseId = courseId;
module.completiondata.courseName = courseName;
// Use of completionstatus is deprecated, use completiondata instead.
module.completionstatus = module.completiondata;
} }
// Check if the module is stealth. // Check if the module is stealth.
@ -1070,7 +1081,13 @@ export class CoreCourseHelperProvider {
if (this.coursesProvider.isGetCoursesByFieldAvailable()) { if (this.coursesProvider.isGetCoursesByFieldAvailable()) {
promises.push(this.coursesProvider.getCoursesByField('id', course.id)); promises.push(this.coursesProvider.getCoursesByField('id', course.id));
} }
promises.push(this.courseProvider.getActivitiesCompletionStatus(course.id));
const sectionWithModules = sections.find((section) => {
return section.modules.length > 0;
});
if (!sectionWithModules || typeof sectionWithModules.modules[0].completion == 'undefined') {
promises.push(this.courseProvider.getActivitiesCompletionStatus(course.id));
}
return this.utils.allPromises(promises); return this.utils.allPromises(promises);
}).then(() => { }).then(() => {

View File

@ -129,6 +129,7 @@ export class CoreCourseSyncProvider extends CoreSyncBaseProvider {
} }
// Get the current completion status to check if any completion was modified in web. // Get the current completion status to check if any completion was modified in web.
// This can be retrieved on core_course_get_contents since 3.6 but this is an easy way to get them.
return this.courseProvider.getActivitiesCompletionStatus(courseId, siteId, undefined, false, true, false) return this.courseProvider.getActivitiesCompletionStatus(courseId, siteId, undefined, false, true, false)
.then((onlineCompletions) => { .then((onlineCompletions) => {
@ -183,7 +184,11 @@ export class CoreCourseSyncProvider extends CoreSyncBaseProvider {
if (result.updated) { if (result.updated) {
// Update data. // Update data.
return this.courseProvider.invalidateSections(courseId, siteId).then(() => { return this.courseProvider.invalidateSections(courseId, siteId).then(() => {
return this.courseProvider.getActivitiesCompletionStatus(courseId); if (this.sitesProvider.getCurrentSite().isVersionGreaterEqualThan('3.6')) {
return this.courseProvider.getSections(courseId, false, true, undefined, siteId);
} else {
return this.courseProvider.getActivitiesCompletionStatus(courseId, siteId);
}
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.
}); });

View File

@ -6,6 +6,7 @@ information provided here is intended especially for developers.
- gulp was updated to v4. In order for gulp to work, you need to install gulp-cli: npm install -g gulp-cli - gulp was updated to v4. In order for gulp to work, you need to install gulp-cli: npm install -g gulp-cli
It's also recommended to update ionic cli to v4, otherwise some errors could be raised while building: npm install -g ionic It's also recommended to update ionic cli to v4, otherwise some errors could be raised while building: npm install -g ionic
- The value of the constant CoreCourseProvider.ALL_SECTIONS_ID has changed from -1 to -2. - The value of the constant CoreCourseProvider.ALL_SECTIONS_ID has changed from -1 to -2.
- Use of completionstatus on the module object has been deprecated, use completiondata instead.
=== 3.5.2 === === 3.5.2 ===