MOBILE-3814 course: Improve course list item performance
parent
54deab86f8
commit
a129a6df9f
|
@ -6,12 +6,27 @@
|
|||
<img *ngIf="course.courseImage" [src]="course.courseImage" core-external-content alt="" />
|
||||
<ion-icon *ngIf="!course.courseImage" name="fas-graduation-cap" class="course-icon">
|
||||
</ion-icon>
|
||||
<ng-container
|
||||
*ngIf="isEnrolled && ((downloadCourseEnabled && !courseOptionMenuEnabled && showDownload) || courseOptionMenuEnabled)">
|
||||
<ng-container *ngTemplateOutlet="download"></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="isEnrolled && layout != 'summarycard'">
|
||||
<div class="core-button-spinner" *ngIf="!courseOptionMenuEnabled && showDownload">
|
||||
<core-download-refresh [status]="prefetchCourseData.status" [enabled]="showDownload"
|
||||
[statusTranslatable]="prefetchCourseData.statusTranslatable" [canTrustDownload]="false"
|
||||
[loading]="prefetchCourseData.loading" (action)="prefetchCourse()"></core-download-refresh>
|
||||
</div>
|
||||
|
||||
<div class="core-button-spinner" *ngIf="courseOptionMenuEnabled">
|
||||
<!-- Options menu. -->
|
||||
<ion-button fill="clear" color="dark" (click)="showCourseOptionsMenu($event)" *ngIf="!showSpinner"
|
||||
[attr.aria-label]="('core.displayoptions' | translate)">
|
||||
<ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<!-- Loading options course spinner. -->
|
||||
<ion-spinner *ngIf="showSpinner" [attr.aria-label]="'core.loading' | translate"></ion-spinner>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ion-item class="ion-text-wrap" button detail="false" (click)="openCourse()" [attr.aria-label]="course.displayname || course.fullname"
|
||||
[class.item-disabled]="course.visible == 0">
|
||||
|
||||
|
@ -46,8 +61,8 @@
|
|||
</ion-icon>
|
||||
</span>
|
||||
|
||||
<ion-icon *ngIf="downloadCourseEnabled && prefetchCourseData.downloadSucceeded" class="core-icon-downloaded"
|
||||
name="cloud-done" color="success" role="status" [attr.aria-label]="'core.downloaded' | translate"></ion-icon>
|
||||
<ion-icon *ngIf="prefetchCourseData.downloadSucceeded" class="core-icon-downloaded" name="cloud-done" color="success"
|
||||
role="status" [attr.aria-label]="'core.downloaded' | translate"></ion-icon>
|
||||
</p>
|
||||
|
||||
<ion-chip color="brand" *ngIf="course.categoryname"
|
||||
|
@ -63,30 +78,7 @@
|
|||
class="core-course-progress">
|
||||
<core-progress-bar [progress]="progress" a11yText="core.courses.aria:courseprogress"></core-progress-bar>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="layout == 'list' || layout == 'listwithenrol' && isEnrolled">
|
||||
<ng-container *ngTemplateOutlet="download"></ng-container>
|
||||
</ng-container>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
</ion-card>
|
||||
|
||||
<ng-template #download>
|
||||
<div class="core-button-spinner" *ngIf="downloadCourseEnabled && !courseOptionMenuEnabled && showDownload">
|
||||
<core-download-refresh [status]="prefetchCourseData.status" [enabled]="downloadCourseEnabled"
|
||||
[statusTranslatable]="prefetchCourseData.statusTranslatable" [canTrustDownload]="false" [loading]="prefetchCourseData.loading"
|
||||
(action)="prefetchCourse()"></core-download-refresh>
|
||||
</div>
|
||||
|
||||
<div class="core-button-spinner" *ngIf="courseOptionMenuEnabled">
|
||||
<!-- Options menu. -->
|
||||
<ion-button fill="clear" color="dark" (click)="showCourseOptionsMenu($event)" *ngIf="!showSpinner"
|
||||
[attr.aria-label]="('core.displayoptions' | translate)">
|
||||
<ion-icon name="ellipsis-vertical" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||
</ion-button>
|
||||
|
||||
<!-- Loading options course spinner. -->
|
||||
<ion-spinner *ngIf="showSpinner" [attr.aria-label]="'core.loading' | translate"></ion-spinner>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
|
|
@ -54,6 +54,7 @@ ion-card {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
z-index: 2;
|
||||
|
||||
ion-spinner {
|
||||
margin-top: 4px;
|
||||
|
@ -156,7 +157,7 @@ ion-card.core-course-list-card {
|
|||
|
||||
ion-icon.course-icon {
|
||||
color: white;
|
||||
opacity: 50%;
|
||||
opacity: 0.5;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
|
|
@ -55,7 +55,6 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
|
|||
};
|
||||
|
||||
showSpinner = false;
|
||||
downloadCourseEnabled = false;
|
||||
courseOptionMenuEnabled = false;
|
||||
progress = -1;
|
||||
completionUserTracked: boolean | undefined = false;
|
||||
|
@ -63,7 +62,6 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
|
|||
protected courseStatus = CoreConstants.NOT_DOWNLOADED;
|
||||
protected isDestroyed = false;
|
||||
protected courseStatusObserver?: CoreEventObserver;
|
||||
protected siteUpdatedObserver?: CoreEventObserver;
|
||||
|
||||
protected element: HTMLElement;
|
||||
|
||||
|
@ -93,31 +91,12 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
|
|||
}
|
||||
|
||||
if (this.isEnrolled) {
|
||||
if (this.showDownload) {
|
||||
this.initPrefetchCourse();
|
||||
}
|
||||
|
||||
this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
|
||||
|
||||
if (this.downloadCourseEnabled) {
|
||||
this.initPrefetchCourse();
|
||||
}
|
||||
|
||||
// This field is only available from 3.6 onwards.
|
||||
this.courseOptionMenuEnabled = (this.layout != 'listwithenrol' && this.layout != 'summarycard') &&
|
||||
this.course.isfavourite !== undefined;
|
||||
|
||||
// Refresh the enabled flag if site is updated.
|
||||
this.siteUpdatedObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, () => {
|
||||
const wasEnabled = this.downloadCourseEnabled;
|
||||
this.initPrefetchCourse();
|
||||
|
||||
this.downloadCourseEnabled = !CoreCourses.isDownloadCourseDisabledInSite();
|
||||
|
||||
if (!wasEnabled && this.downloadCourseEnabled) {
|
||||
// Download course is enabled now, initialize it.
|
||||
this.initPrefetchCourse();
|
||||
}
|
||||
}, CoreSites.getCurrentSiteId());
|
||||
} else if ('enrollmentmethods' in this.course) {
|
||||
this.enrolmentIcons = [];
|
||||
|
||||
|
@ -169,9 +148,7 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
|
|||
* @inheritdoc
|
||||
*/
|
||||
ngOnChanges(): void {
|
||||
if (this.showDownload && this.isEnrolled) {
|
||||
this.initPrefetchCourse();
|
||||
}
|
||||
this.initPrefetchCourse();
|
||||
|
||||
this.updateCourseFields();
|
||||
}
|
||||
|
@ -203,7 +180,12 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
|
|||
/**
|
||||
* Initialize prefetch course.
|
||||
*/
|
||||
async initPrefetchCourse(): Promise<void> {
|
||||
async initPrefetchCourse(forceInit = false): Promise<void> {
|
||||
if (!this.isEnrolled || !this.showDownload ||
|
||||
(this.courseOptionMenuEnabled && !forceInit)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.courseStatusObserver !== undefined) {
|
||||
// Already initialized.
|
||||
return;
|
||||
|
@ -306,6 +288,8 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
|
|||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
this.initPrefetchCourse(true);
|
||||
|
||||
const popoverData = await CoreDomUtils.openPopover<string>({
|
||||
component: CoreCoursesCourseOptionsMenuComponent,
|
||||
componentProps: {
|
||||
|
@ -414,7 +398,6 @@ export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, On
|
|||
ngOnDestroy(): void {
|
||||
this.isDestroyed = true;
|
||||
this.courseStatusObserver?.off();
|
||||
this.siteUpdatedObserver?.off();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -201,6 +201,7 @@ ion-header ion-toolbar {
|
|||
.in-toolbar.button-clear {
|
||||
--color: var(--core-header-toolbar-color);
|
||||
--ion-toolbar-color: var(--core-header-toolbar-color);
|
||||
--border-radius: var(--huge-radius);
|
||||
}
|
||||
|
||||
.button.button-clear,
|
||||
|
|
Loading…
Reference in New Issue