forked from EVOgeek/Vmeda.Online
		
	MOBILE-2746 UX: Only refresh page if completion value is used
Now that completion data includes valueused, we can refresh the page in response to a completion change only when valueused is true. It is is false, we can update the checkbox and progress bar client-side.
This commit is contained in:
		
							parent
							
								
									c1326f70da
								
							
						
					
					
						commit
						6338005c94
					
				| @ -82,7 +82,7 @@ | |||||||
|         </ion-item> |         </ion-item> | ||||||
| 
 | 
 | ||||||
|         <ng-container *ngFor="let module of section.modules"> |         <ng-container *ngFor="let module of section.modules"> | ||||||
|             <core-course-module *ngIf="module.visibleoncoursepage !== 0" [module]="module" [courseId]="course.id" [downloadEnabled]="downloadEnabled" [section]="section" (completionChanged)="completionChanged.emit()"></core-course-module> |             <core-course-module *ngIf="module.visibleoncoursepage !== 0" [module]="module" [courseId]="course.id" [downloadEnabled]="downloadEnabled" [section]="section" (completionChanged)="onCompletionChange($event)"></core-course-module> | ||||||
|         </ng-container> |         </ng-container> | ||||||
|     </section> |     </section> | ||||||
| </ng-template> | </ng-template> | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|     @Input() initialSectionId?: number; // The section to load first (by ID).
 |     @Input() initialSectionId?: number; // The section to load first (by ID).
 | ||||||
|     @Input() initialSectionNumber?: number; // The section to load first (by number).
 |     @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.
 |     @Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section.
 | ||||||
|     @Output() completionChanged?: EventEmitter<void>; // Will emit an event when any module completion changes.
 |     @Output() completionChanged?: EventEmitter<any>; // Will emit an event when any module completion changes.
 | ||||||
| 
 | 
 | ||||||
|     @ViewChildren(CoreDynamicComponent) dynamicComponents: QueryList<CoreDynamicComponent>; |     @ViewChildren(CoreDynamicComponent) dynamicComponents: QueryList<CoreDynamicComponent>; | ||||||
| 
 | 
 | ||||||
| @ -461,4 +461,28 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|         return section.uservisible !== false && !section.hiddenbynumsections && |         return section.uservisible !== false && !section.hiddenbynumsections && | ||||||
|                 section.id != CoreCourseProvider.STEALTH_MODULES_SECTION_ID; |                 section.id != CoreCourseProvider.STEALTH_MODULES_SECTION_ID; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * The completion of any of the modules have changed. | ||||||
|  |      */ | ||||||
|  |     onCompletionChange(completionData: any): void { | ||||||
|  |         if (completionData.hasOwnProperty('valueused') && !completionData.valueused) { | ||||||
|  |             // If the completion value is not used, the page won't be reloaded, so update the progress bar.
 | ||||||
|  |             const completionModules = [] | ||||||
|  |                     .concat(...this.sections.filter((section) => section.hasOwnProperty('modules')) | ||||||
|  |                         .map((section) => section.modules)) | ||||||
|  |                     .map((module) => (module.completion > 0) ? 1 : module.completion) | ||||||
|  |                     .reduce((accumulator, currentValue) => accumulator + currentValue); | ||||||
|  |             const moduleProgressPercent = 100 / completionModules; | ||||||
|  |             // Use min/max here to avoid floating point rounding errors over/under-flowing the progress bar.
 | ||||||
|  |             if (completionData.state === CoreCourseProvider.COMPLETION_COMPLETE) { | ||||||
|  |                 this.course.progress = Math.min(100, this.course.progress + moduleProgressPercent); | ||||||
|  |             } else { | ||||||
|  |                 this.course.progress = Math.max(0, this.course.progress - moduleProgressPercent); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |         // Emit a new event for other components.
 | ||||||
|  |         this.completionChanged.emit(completionData); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -35,7 +35,7 @@ import { CoreCourseProvider } from '../../providers/course'; | |||||||
| export class CoreCourseModuleCompletionComponent implements OnChanges { | export class CoreCourseModuleCompletionComponent implements OnChanges { | ||||||
|     @Input() completion: any; // The completion status.
 |     @Input() completion: any; // The completion status.
 | ||||||
|     @Input() moduleName?: string; // The name of the module this completion affects.
 |     @Input() moduleName?: string; // The name of the module this completion affects.
 | ||||||
|     @Output() completionChanged?: EventEmitter<void>; // Will emit an event when the completion changes.
 |     @Output() completionChanged?: EventEmitter<any>; // Will emit an event when the completion changes.
 | ||||||
| 
 | 
 | ||||||
|     completionImage: string; |     completionImage: string; | ||||||
|     completionDescription: string; |     completionDescription: string; | ||||||
| @ -71,15 +71,23 @@ export class CoreCourseModuleCompletionComponent implements OnChanges { | |||||||
| 
 | 
 | ||||||
|             const modal = this.domUtils.showModalLoading(); |             const modal = this.domUtils.showModalLoading(); | ||||||
| 
 | 
 | ||||||
|             this.courseProvider.markCompletedManually(this.completion.cmid, this.completion.state === 1 ? 0 : 1, |             this.completion.state = this.completion.state === 1 ? 0 : 1; | ||||||
|  |             this.courseProvider.markCompletedManually(this.completion.cmid, this.completion.state, | ||||||
|                     this.completion.courseId, this.completion.courseName).then((response) => { |                     this.completion.courseId, this.completion.courseName).then((response) => { | ||||||
| 
 | 
 | ||||||
|                 if (!response.status) { |                 if (!response.status) { | ||||||
|                     return Promise.reject(null); |                     return Promise.reject(null); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 this.completionChanged.emit(); |                 if (this.completion.hasOwnProperty('valueused') && !this.completion.valueused) { | ||||||
|  |                     this.showStatus(); | ||||||
|  |                     if (response.offline) { | ||||||
|  |                         this.completion.offline = true; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 this.completionChanged.emit(this.completion); | ||||||
|             }).catch((error) => { |             }).catch((error) => { | ||||||
|  |                 this.completion.state = this.completion.state === 1 ? 0 : 1; | ||||||
|                 this.domUtils.showErrorModalDefault(error, 'core.errorchangecompletion', true); |                 this.domUtils.showErrorModalDefault(error, 'core.errorchangecompletion', true); | ||||||
|             }).finally(() => { |             }).finally(() => { | ||||||
|                 modal.dismiss(); |                 modal.dismiss(); | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ | |||||||
|         <!-- Buttons. --> |         <!-- Buttons. --> | ||||||
|         <div item-end *ngIf="module.uservisible !== false" class="buttons core-module-buttons" [ngClass]="{'core-button-completion': module.completiondata}"> |         <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.completiondata" [completion]="module.completiondata" [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($event)"></core-course-module-completion> | ||||||
| 
 | 
 | ||||||
|             <div class="core-module-buttons-more"> |             <div class="core-module-buttons-more"> | ||||||
|                 <!-- Download button. --> |                 <!-- Download button. --> | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy { | |||||||
|             this.prefetchDelegate.getModuleStatus(this.module, this.courseId).then(this.showStatus.bind(this)); |             this.prefetchDelegate.getModuleStatus(this.module, this.courseId).then(this.showStatus.bind(this)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     @Output() completionChanged?: EventEmitter<void>; // Will emit an event when the module completion changes.
 |     @Output() completionChanged?: EventEmitter<any>; // Will emit an event when the module completion changes.
 | ||||||
| 
 | 
 | ||||||
|     showDownload: boolean; // Whether to display the download button.
 |     showDownload: boolean; // Whether to display the download button.
 | ||||||
|     showRefresh: boolean; // Whether to display the refresh button.
 |     showRefresh: boolean; // Whether to display the refresh button.
 | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ | |||||||
|                     </ion-refresher> |                     </ion-refresher> | ||||||
| 
 | 
 | ||||||
|                     <core-loading [hideUntil]="dataLoaded"> |                     <core-loading [hideUntil]="dataLoaded"> | ||||||
|                         <core-course-format [course]="course" [sections]="sections" [initialSectionId]="sectionId" [initialSectionNumber]="sectionNumber" [downloadEnabled]="downloadEnabled" [moduleId]="moduleId" (completionChanged)="onCompletionChange()"></core-course-format> |                         <core-course-format [course]="course" [sections]="sections" [initialSectionId]="sectionId" [initialSectionNumber]="sectionNumber" [downloadEnabled]="downloadEnabled" [moduleId]="moduleId" (completionChanged)="onCompletionChange($event)"></core-course-format> | ||||||
|                     </core-loading> |                     </core-loading> | ||||||
|                 </ion-content> |                 </ion-content> | ||||||
|             </ng-template> |             </ng-template> | ||||||
|  | |||||||
| @ -347,9 +347,12 @@ export class CoreCourseSectionPage implements OnDestroy { | |||||||
|     /** |     /** | ||||||
|      * The completion of any of the modules have changed. |      * The completion of any of the modules have changed. | ||||||
|      */ |      */ | ||||||
|     onCompletionChange(): void { |     onCompletionChange(completionData: any): void { | ||||||
|  |         const shouldReload = !completionData.hasOwnProperty('valueused') || completionData.valueused; | ||||||
|         this.invalidateData().finally(() => { |         this.invalidateData().finally(() => { | ||||||
|             this.refreshAfterCompletionChange(true); |             if (shouldReload) { | ||||||
|  |                 this.refreshAfterCompletionChange(true); | ||||||
|  |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user