MOBILE-3686 courses: Add download options to course list item
parent
8acb8b74e2
commit
ad45289f4b
|
@ -34,4 +34,14 @@
|
|||
slot="end">
|
||||
</ion-icon>
|
||||
</ng-container>
|
||||
|
||||
<div class="core-button-spinner" *ngIf="isEnrolled && showDownload" slot="end">
|
||||
<core-download-refresh
|
||||
[status]="prefetchCourseData.status"
|
||||
[statusTranslatable]="prefetchCourseData.statusTranslatable"
|
||||
[enabled]="true"
|
||||
canTrustDownload="false"
|
||||
[loading]="prefetchCourseData.loading"
|
||||
(action)="prefetchCourse()"></core-download-refresh>
|
||||
</div>
|
||||
</ion-item>
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { CoreCourseHelper } from '@features/course/services/course-helper';
|
||||
import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core';
|
||||
import { CoreCourseProvider, CoreCourse } from '@features/course/services/course';
|
||||
import { CoreCourseHelper, CorePrefetchStatusInfo } from '@features/course/services/course-helper';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
|
@ -33,15 +34,26 @@ import { CoreCoursesHelper } from '../../services/courses-helper';
|
|||
templateUrl: 'core-courses-course-list-item.html',
|
||||
styleUrls: ['course-list-item.scss'],
|
||||
})
|
||||
export class CoreCoursesCourseListItemComponent implements OnInit {
|
||||
export class CoreCoursesCourseListItemComponent implements OnInit, OnDestroy, OnChanges {
|
||||
|
||||
@Input() course!: CoreCourseListItem; // The course to render.
|
||||
|
||||
@Input() showDownload = false; // If true, will show download button.
|
||||
|
||||
icons: CoreCoursesEnrolmentIcons[] = [];
|
||||
isEnrolled = false;
|
||||
prefetchCourseData: CorePrefetchStatusInfo = {
|
||||
icon: '',
|
||||
statusTranslatable: 'core.loading',
|
||||
status: '',
|
||||
loading: true,
|
||||
};
|
||||
|
||||
protected courseStatusObserver?: CoreEventObserver;
|
||||
protected isDestroyed = false;
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
* @inheritdoc
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
CoreCoursesHelper.loadCourseColorAndImage(this.course);
|
||||
|
@ -55,6 +67,10 @@ export class CoreCoursesCourseListItemComponent implements OnInit {
|
|||
this.course.completionusertracked = course.completionusertracked;
|
||||
|
||||
this.isEnrolled = true;
|
||||
|
||||
if (this.showDownload) {
|
||||
this.initPrefetchCourse();
|
||||
}
|
||||
} catch {
|
||||
this.isEnrolled = false;
|
||||
}
|
||||
|
@ -91,6 +107,15 @@ export class CoreCoursesCourseListItemComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ngOnChanges(): void {
|
||||
if (this.showDownload && this.isEnrolled) {
|
||||
this.initPrefetchCourse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a course.
|
||||
*
|
||||
|
@ -107,6 +132,85 @@ export class CoreCoursesCourseListItemComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize prefetch course.
|
||||
*/
|
||||
async initPrefetchCourse(): Promise<void> {
|
||||
if (this.courseStatusObserver !== undefined) {
|
||||
// Already initialized.
|
||||
return;
|
||||
}
|
||||
|
||||
// Listen for status change in course.
|
||||
this.courseStatusObserver = CoreEvents.on(CoreEvents.COURSE_STATUS_CHANGED, (data: CoreEventCourseStatusChanged) => {
|
||||
if (data.courseId == this.course.id || data.courseId == CoreCourseProvider.ALL_COURSES_CLEARED) {
|
||||
this.updateCourseStatus(data.status);
|
||||
}
|
||||
}, CoreSites.getCurrentSiteId());
|
||||
|
||||
// Determine course prefetch icon.
|
||||
const status = await CoreCourse.getCourseStatus(this.course.id);
|
||||
|
||||
this.updateCourseStatus(status);
|
||||
|
||||
if (this.prefetchCourseData.loading) {
|
||||
// Course is being downloaded. Get the download promise.
|
||||
const promise = CoreCourseHelper.getCourseDownloadPromise(this.course.id);
|
||||
if (promise) {
|
||||
// There is a download promise. If it fails, show an error.
|
||||
promise.catch((error) => {
|
||||
if (!this.isDestroyed) {
|
||||
CoreDomUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// No download, this probably means that the app was closed while downloading. Set previous status.
|
||||
CoreCourse.setCoursePreviousStatus(this.course.id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the course status icon and title.
|
||||
*
|
||||
* @param status Status to show.
|
||||
*/
|
||||
protected updateCourseStatus(status: string): void {
|
||||
const statusData = CoreCourseHelper.getCoursePrefetchStatusInfo(status);
|
||||
|
||||
this.prefetchCourseData.status = statusData.status;
|
||||
this.prefetchCourseData.icon = statusData.icon;
|
||||
this.prefetchCourseData.statusTranslatable = statusData.statusTranslatable;
|
||||
this.prefetchCourseData.loading = statusData.loading;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch the course.
|
||||
*
|
||||
* @param e Click event.
|
||||
*/
|
||||
async prefetchCourse(e?: Event): Promise<void> {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
|
||||
try {
|
||||
await CoreCourseHelper.confirmAndPrefetchCourse(this.prefetchCourseData, this.course);
|
||||
} catch (error) {
|
||||
if (!this.isDestroyed) {
|
||||
CoreDomUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.isDestroyed = true;
|
||||
this.courseStatusObserver?.off();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,8 +48,6 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy, On
|
|||
@Input() showAll = false; // If true, will show all actions, options, star and progress.
|
||||
@Input() showDownload = true; // If true, will show download button. Only works if the options menu is not shown.
|
||||
|
||||
courseStatus = CoreConstants.NOT_DOWNLOADED;
|
||||
isDownloading = false;
|
||||
prefetchCourseData: CorePrefetchStatusInfo = {
|
||||
icon: '',
|
||||
statusTranslatable: 'core.loading',
|
||||
|
@ -64,6 +62,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy, On
|
|||
progress = -1;
|
||||
completionUserTracked: boolean | undefined = false;
|
||||
|
||||
protected courseStatus = CoreConstants.NOT_DOWNLOADED;
|
||||
protected isDestroyed = false;
|
||||
protected courseStatusObserver?: CoreEventObserver;
|
||||
protected siteUpdatedObserver?: CoreEventObserver;
|
||||
|
@ -109,7 +108,7 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy, On
|
|||
* Initialize prefetch course.
|
||||
*/
|
||||
async initPrefetchCourse(): Promise<void> {
|
||||
if (typeof this.courseStatusObserver != 'undefined') {
|
||||
if (this.courseStatusObserver !== undefined) {
|
||||
// Already initialized.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
</ion-item-divider>
|
||||
</ng-container>
|
||||
|
||||
<core-courses-course-list-item *ngFor="let course of courses" [course]="course"></core-courses-course-list-item>
|
||||
<core-courses-course-list-item *ngFor="let course of courses" [course]="course" [showDownload]="downloadEnabled">
|
||||
</core-courses-course-list-item>
|
||||
|
||||
<core-infinite-loading [enabled]="searchMode && searchCanLoadMore" (action)="loadMoreResults($event)" [error]="searchLoadMoreError">
|
||||
</core-infinite-loading>
|
||||
|
|
Loading…
Reference in New Issue