diff --git a/src/core/directives/collapsible-header.ts b/src/core/directives/collapsible-header.ts index 970195123..95c31c943 100644 --- a/src/core/directives/collapsible-header.ts +++ b/src/core/directives/collapsible-header.ts @@ -297,13 +297,16 @@ export class CoreCollapsibleHeaderDirective implements OnDestroy { const collapsibleHeaderHeight = this.title.shadowRoot?.children[0].clientHeight ?? this.title.clientHeight; const scrollableHeight = this.contentScroll.scrollHeight - this.contentScroll.clientHeight; const collapsedHeight = collapsibleHeaderHeight - this.title.clientHeight; - const progress = CoreMath.clamp( - scrollableHeight + collapsedHeight <= 2 * collapsibleHeaderHeight - ? this.contentScroll.scrollTop / (this.contentScroll.scrollHeight - this.contentScroll.clientHeight) - : this.contentScroll.scrollTop / collapsibleHeaderHeight, - 0, - 1, - ); + let progress = 0; + if (scrollableHeight !== 0) { + progress = CoreMath.clamp( + scrollableHeight + collapsedHeight <= 2 * collapsibleHeaderHeight + ? this.contentScroll.scrollTop / scrollableHeight + : this.contentScroll.scrollTop / collapsibleHeaderHeight, + 0, + 1, + ); + } const collapsed = progress === 1; if (!this.inContent) { diff --git a/src/core/features/course/components/module-completion-legacy/module-completion-legacy.ts b/src/core/features/course/components/module-completion-legacy/module-completion-legacy.ts index 3f10eefa4..f7c5b55e8 100644 --- a/src/core/features/course/components/module-completion-legacy/module-completion-legacy.ts +++ b/src/core/features/course/components/module-completion-legacy/module-completion-legacy.ts @@ -16,7 +16,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { CoreUser } from '@features/user/services/user'; import { - CoreCourseCompletionType, CoreCourseModuleCompletionStatus, CoreCourseModuleCompletionTracking, } from '@features/course/services/course'; @@ -52,8 +51,8 @@ export class CoreCourseModuleCompletionLegacyComponent extends CoreCourseModuleC * @inheritdoc */ ngOnInit(): void { - this.completionObserver = CoreEvents.on(CoreEvents.COMPLETION_CHANGED, (data) => { - if (!this.completion || this.completion.cmid != data.completion.cmid || data.type != CoreCourseCompletionType.MANUAL) { + this.completionObserver = CoreEvents.on(CoreEvents.MANUAL_COMPLETION_CHANGED, (data) => { + if (!this.completion || this.completion.cmid != data.completion.cmid) { return; } @@ -149,9 +148,7 @@ export class CoreCourseModuleCompletionLegacyComponent extends CoreCourseModuleC await CoreCourseHelper.changeManualCompletion(this.completion, event); - // @deprecated MANUAL_COMPLETION_CHANGED is deprecated since 4.0 use COMPLETION_CHANGED instead. CoreEvents.trigger(CoreEvents.MANUAL_COMPLETION_CHANGED, { completion: this.completion }); - CoreEvents.trigger(CoreEvents.COMPLETION_CHANGED, { completion: this.completion, type: CoreCourseCompletionType.MANUAL }); } /** diff --git a/src/core/features/course/components/module-manual-completion/module-manual-completion.ts b/src/core/features/course/components/module-manual-completion/module-manual-completion.ts index f2468cdab..5d3c51f4f 100644 --- a/src/core/features/course/components/module-manual-completion/module-manual-completion.ts +++ b/src/core/features/course/components/module-manual-completion/module-manual-completion.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChange } from '@angular/core'; -import { CoreCourseCompletionMode, CoreCourseCompletionType } from '@features/course/services/course'; +import { CoreCourseCompletionMode } from '@features/course/services/course'; import { CoreCourseHelper, CoreCourseModuleCompletionData } from '@features/course/services/course-helper'; import { CoreUser } from '@features/user/services/user'; import { Translate } from '@singletons'; @@ -41,8 +41,8 @@ export class CoreCourseModuleManualCompletionComponent implements OnInit, OnChan * @inheritdoc */ ngOnInit(): void { - this.completionObserver = CoreEvents.on(CoreEvents.COMPLETION_CHANGED, (data) => { - if (!this.completion || this.completion.cmid != data.completion.cmid || data.type != CoreCourseCompletionType.MANUAL) { + this.completionObserver = CoreEvents.on(CoreEvents.MANUAL_COMPLETION_CHANGED, (data) => { + if (!this.completion || this.completion.cmid != data.completion.cmid) { return; } @@ -102,9 +102,7 @@ export class CoreCourseModuleManualCompletionComponent implements OnInit, OnChan await CoreCourseHelper.changeManualCompletion(this.completion, event); - // @deprecated MANUAL_COMPLETION_CHANGED is deprecated since 4.0 use COMPLETION_CHANGED instead. CoreEvents.trigger(CoreEvents.MANUAL_COMPLETION_CHANGED, { completion: this.completion }); - CoreEvents.trigger(CoreEvents.COMPLETION_CHANGED, { completion: this.completion, type: CoreCourseCompletionType.MANUAL }); } /** diff --git a/src/core/features/course/pages/contents/contents.html b/src/core/features/course/pages/contents/contents.html index b12da3cc6..64ff48a05 100644 --- a/src/core/features/course/pages/contents/contents.html +++ b/src/core/features/course/pages/contents/contents.html @@ -7,8 +7,7 @@ + [moduleId]="moduleId" class="core-course-format-{{course.format}}" *ngIf="dataLoaded"> diff --git a/src/core/features/course/pages/contents/contents.ts b/src/core/features/course/pages/contents/contents.ts index 26c407028..77d752743 100644 --- a/src/core/features/course/pages/contents/contents.ts +++ b/src/core/features/course/pages/contents/contents.ts @@ -63,6 +63,7 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { protected formatOptions?: Record; protected completionObserver?: CoreEventObserver; + protected manualCompletionObserver?: CoreEventObserver; protected syncObserver?: CoreEventObserver; protected isDestroyed = false; protected modulesHaveCompletion = false; @@ -114,36 +115,40 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { * @return Promise resolved when done. */ protected async initListeners(): Promise { + if (this.completionObserver) { + return; // Already initialized. + } + // Check if the course format requires the view to be refreshed when completion changes. const shouldRefresh = await CoreCourseFormatDelegate.shouldRefreshWhenCompletionChanges(this.course); if (!shouldRefresh) { return; } - if (!this.completionObserver) { - this.completionObserver = CoreEvents.on( - CoreEvents.COMPLETION_MODULE_VIEWED, - (data) => { - if (data && data.courseId == this.course.id) { - this.refreshAfterCompletionChange(true); - } - }, - ); - } - - if (!this.syncObserver) { - this.syncObserver = CoreEvents.on(CoreCourseSyncProvider.AUTO_SYNCED, (data) => { - if (!data || data.courseId != this.course.id) { - return; + this.completionObserver = CoreEvents.on( + CoreEvents.COMPLETION_MODULE_VIEWED, + (data) => { + if (data && data.courseId == this.course.id) { + this.refreshAfterCompletionChange(true); } + }, + ); - this.refreshAfterCompletionChange(false); + this.manualCompletionObserver = CoreEvents.on(CoreEvents.MANUAL_COMPLETION_CHANGED, (data) => { + this.onCompletionChange(data.completion); + }); - if (data.warnings && data.warnings[0]) { - CoreDomUtils.showErrorModal(data.warnings[0]); - } - }); - } + this.syncObserver = CoreEvents.on(CoreCourseSyncProvider.AUTO_SYNCED, (data) => { + if (!data || data.courseId != this.course.id) { + return; + } + + this.refreshAfterCompletionChange(false); + + if (data.warnings && data.warnings[0]) { + CoreDomUtils.showErrorModal(data.warnings[0]); + } + }); } /** @@ -369,6 +374,7 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { ngOnDestroy(): void { this.isDestroyed = true; this.completionObserver?.off(); + this.manualCompletionObserver?.off(); this.syncObserver?.off(); } diff --git a/src/core/features/course/pages/index/index.ts b/src/core/features/course/pages/index/index.ts index 9991c008d..56e10b136 100644 --- a/src/core/features/course/pages/index/index.ts +++ b/src/core/features/course/pages/index/index.ts @@ -88,7 +88,7 @@ export class CoreCourseIndexPage implements OnInit, OnDestroy { }); // The completion of any of the modules have changed. - this.completionObserver = CoreEvents.on(CoreEvents.COMPLETION_CHANGED, (data) => { + this.completionObserver = CoreEvents.on(CoreEvents.MANUAL_COMPLETION_CHANGED, (data) => { if (data.completion.courseId != this.course?.id) { return; } diff --git a/src/core/features/course/services/course.ts b/src/core/features/course/services/course.ts index 5e1496358..55c7fc262 100644 --- a/src/core/features/course/services/course.ts +++ b/src/core/features/course/services/course.ts @@ -75,11 +75,6 @@ export enum CoreCourseModuleCompletionStatus { COMPLETION_COMPLETE_FAIL = 3, } -export enum CoreCourseCompletionType { - MANUAL = 0, - AUTO = 1, -} - export enum CoreCourseCompletionMode { FULL = 'full', BASIC = 'basic', diff --git a/src/core/features/siteplugins/components/course-format/course-format.ts b/src/core/features/siteplugins/components/course-format/course-format.ts index 3f87875e8..d2bc5c401 100644 --- a/src/core/features/siteplugins/components/course-format/course-format.ts +++ b/src/core/features/siteplugins/components/course-format/course-format.ts @@ -37,7 +37,8 @@ export class CoreSitePluginsCourseFormatComponent implements OnChanges { @Input() initialSectionId?: number; // The section to load first (by ID). @Input() initialSectionNumber?: number; // The section to load first (by number). @Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section. - @Output() completionChanged = new EventEmitter(); // Notify when any module completion changes. + // Notify when any module completion changes. @deprecated since 4.0, now we use CoreEvents. + @Output() completionChanged = new EventEmitter(); // Special input, allows access to the parent instance properties and methods. // Please notice that all the other inputs/outputs are also accessible through this instance, so they could be removed. diff --git a/src/core/singletons/events.ts b/src/core/singletons/events.ts index 84b8522d3..57d112fd8 100644 --- a/src/core/singletons/events.ts +++ b/src/core/singletons/events.ts @@ -20,7 +20,6 @@ import { CoreFilepoolComponentFileEventData } from '@services/filepool'; import { CoreRedirectPayload } from '@services/navigator'; import { CoreCourseModuleCompletionData } from '@features/course/services/course-helper'; import { CoreScreenOrientation } from '@services/screen'; -import { CoreCourseCompletionType } from '@features/course/services/course'; /** * Observer instance to stop listening to an event. @@ -51,7 +50,6 @@ export interface CoreEventsData { [CoreEvents.SELECT_COURSE_TAB]: CoreEventSelectCourseTabData; [CoreEvents.COMPLETION_MODULE_VIEWED]: CoreEventCompletionModuleViewedData; [CoreEvents.MANUAL_COMPLETION_CHANGED]: CoreEventManualCompletionChangedData; - [CoreEvents.COMPLETION_CHANGED]: CoreEventCompletionChangedData; [CoreEvents.SECTION_STATUS_CHANGED]: CoreEventSectionStatusChangedData; [CoreEvents.ACTIVITY_DATA_SENT]: CoreEventActivityDataSentData; [CoreEvents.IAB_LOAD_START]: InAppBrowserEvent; @@ -371,14 +369,6 @@ export type CoreEventManualCompletionChangedData = { completion: CoreCourseModuleCompletionData; }; -/** - * Data passed to COMPLETION_CHANGED event. - */ -export type CoreEventCompletionChangedData = { - completion: CoreCourseModuleCompletionData; - type: CoreCourseCompletionType; -}; - /** * Data passed to SECTION_STATUS_CHANGED event. */