MOBILE-2310 courses: Apply download courses
parent
fe2c4cce74
commit
04085d5929
|
@ -242,6 +242,10 @@ export class CoreCourseSectionPage implements OnDestroy {
|
|||
// Ignore errors (shouldn't happen).
|
||||
});
|
||||
}
|
||||
}).catch((error) => {
|
||||
if (!this.isDestroyed) {
|
||||
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
<a ion-item text-wrap detail-none (click)="openCourse(course)" [title]="course.fullname">
|
||||
<h2 float-start><core-format-text [text]="course.fullname"></core-format-text></h2>
|
||||
<!-- Download course. -->
|
||||
<!--<button [hidden]="!downloadButton.isDownload" ion-button icon-only clear color="dark" float-end>
|
||||
<ion-icon name="cloud-download"></ion-icon>
|
||||
</button>-->
|
||||
<button *ngIf="prefetchCourseData.prefetchCourseIcon != 'spinner'" ion-button icon-only clear color="dark" float-end (click)="prefetchCourse($event)">
|
||||
<ion-icon [name]="prefetchCourseData.prefetchCourseIcon"></ion-icon>
|
||||
</button>
|
||||
<!-- Download course spinner. -->
|
||||
<!-- <ion-spinner *ngIf="prefetchCourseIcon == 'spinner'" class="core-course-download-spinner"></ion-spinner> -->
|
||||
<ion-spinner *ngIf="prefetchCourseData.prefetchCourseIcon == 'spinner'" class="core-course-download-spinner" float-end></ion-spinner>
|
||||
</a>
|
||||
<ion-item text-wrap *ngIf="course.summary && course.summary.length">
|
||||
<p>
|
||||
|
|
|
@ -12,10 +12,15 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
|
||||
import { NavController } from 'ionic-angular';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreEventsProvider } from '../../../../providers/events';
|
||||
import { CoreSitesProvider } from '../../../../providers/sites';
|
||||
import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
|
||||
import { CoreCourseFormatDelegate } from '../../../course/providers/format-delegate';
|
||||
import { CoreCourseProvider } from '../../../course/providers/course';
|
||||
import { CoreCourseHelperProvider } from '../../../course/providers/helper';
|
||||
|
||||
/**
|
||||
* This component is meant to display a course for a list of courses with progress.
|
||||
|
@ -29,32 +34,52 @@ import { CoreCourseFormatDelegate } from '../../../course/providers/format-deleg
|
|||
selector: 'core-courses-course-progress',
|
||||
templateUrl: 'course-progress.html'
|
||||
})
|
||||
export class CoreCoursesCourseProgressComponent implements OnInit {
|
||||
export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy {
|
||||
@Input() course: any; // The course to render.
|
||||
|
||||
isDownloading: boolean;
|
||||
|
||||
protected obsStatus;
|
||||
protected downloadText;
|
||||
protected downloadingText;
|
||||
protected downloadButton = {
|
||||
isDownload: true,
|
||||
className: 'core-download-course',
|
||||
priority: 1000
|
||||
prefetchCourseData = {
|
||||
prefetchCourseIcon: 'spinner'
|
||||
};
|
||||
protected buttons;
|
||||
|
||||
constructor(private navCtrl: NavController, private translate: TranslateService,
|
||||
private courseFormatDelegate: CoreCourseFormatDelegate) {
|
||||
this.downloadText = this.translate.instant('core.course.downloadcourse');
|
||||
this.downloadingText = this.translate.instant('core.downloading');
|
||||
protected isDestroyed = false;
|
||||
protected courseStatusObserver;
|
||||
|
||||
constructor(private navCtrl: NavController, private translate: TranslateService, private courseHelper: CoreCourseHelperProvider,
|
||||
private courseFormatDelegate: CoreCourseFormatDelegate, private domUtils: CoreDomUtilsProvider,
|
||||
private courseProvider: CoreCourseProvider, eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider) {
|
||||
// Listen for status change in course.
|
||||
this.courseStatusObserver = eventsProvider.on(CoreEventsProvider.COURSE_STATUS_CHANGED, (data) => {
|
||||
if (data.courseId == this.course.id) {
|
||||
this.prefetchCourseData.prefetchCourseIcon = this.courseHelper.getCourseStatusIconFromStatus(data.status);
|
||||
}
|
||||
}, sitesProvider.getCurrentSiteId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit() {
|
||||
// @todo: Handle course prefetch.
|
||||
// Determine course prefetch icon.
|
||||
this.courseHelper.getCourseStatusIcon(this.course.id).then((icon) => {
|
||||
this.prefetchCourseData.prefetchCourseIcon = icon;
|
||||
|
||||
if (icon == 'spinner') {
|
||||
// Course is being downloaded. Get the download promise.
|
||||
const promise = this.courseHelper.getCourseDownloadPromise(this.course.id);
|
||||
if (promise) {
|
||||
// There is a download promise. If it fails, show an error.
|
||||
promise.catch((error) => {
|
||||
if (!this.isDestroyed) {
|
||||
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// No download, this probably means that the app was closed while downloading. Set previous status.
|
||||
this.courseProvider.setCoursePreviousStatus(this.course.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,4 +89,30 @@ export class CoreCoursesCourseProgressComponent implements OnInit {
|
|||
this.courseFormatDelegate.openCourse(this.navCtrl, course);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch the course.
|
||||
*
|
||||
* @param {Event} e Click event.
|
||||
*/
|
||||
prefetchCourse(e: Event) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.courseHelper.confirmAndPrefetchCourse(this.prefetchCourseData, this.course).catch((error) => {
|
||||
if (!this.isDestroyed) {
|
||||
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Component destroyed.
|
||||
*/
|
||||
ngOnDestroy() {
|
||||
this.isDestroyed = true;
|
||||
|
||||
if (this.courseStatusObserver) {
|
||||
this.courseStatusObserver.off();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,22 +17,22 @@
|
|||
<p *ngIf="course.startdate">{{course.startdate * 1000 | coreFormatDate:"dfdaymonthyear"}} <span *ngIf="course.enddate"> - {{course.enddate * 1000 | coreFormatDate:"dfdaymonthyear"}}</span></p>
|
||||
</a>
|
||||
|
||||
<ion-item text-wrap *ngIf="course.summary">
|
||||
<ion-item text-wrap *ngIf="course.summary" detail-none>
|
||||
<core-format-text [text]="course.summary" maxHeight="120"></core-format-text>
|
||||
</ion-item>
|
||||
|
||||
<a ion-item text-wrap *ngIf="course.contacts && course.contacts.length" core-user-link [attr.aria-label]="'core.viewprofile' | translate">
|
||||
<a ion-item text-wrap *ngIf="course.contacts && course.contacts.length" detail-none>
|
||||
<p class="item-heading">{{ 'core.teachers' | translate }}</p>
|
||||
<p *ngFor="let contact of course.contacts">{{contact.fullname}}</p>
|
||||
</a>
|
||||
<core-file *ngFor="let file of course.overviewfiles" [file]="file" [component]="component" [componentId]="course.id"></core-file>
|
||||
<div *ngIf="!isEnrolled">
|
||||
<div *ngIf="!isEnrolled" detail-none>
|
||||
<ion-item text-wrap *ngFor="let instance of selfEnrolInstances">
|
||||
<p class="item-heading">{{ instance.name }}</p>
|
||||
<button ion-button block margin-top (click)="selfEnrolClicked(instance.id)">{{ 'core.courses.enrolme' | translate }}</button>
|
||||
</ion-item>
|
||||
</div>
|
||||
<ion-item text-wrap *ngIf="!isEnrolled && paypalEnabled">
|
||||
<ion-item text-wrap *ngIf="!isEnrolled && paypalEnabled" detail-none>
|
||||
<p class="item-heading">{{ 'core.courses.paypalaccepted' | translate }}</p>
|
||||
<p>{{ 'core.paymentinstant' | translate }}</p>
|
||||
<button ion-button block margin-top (click)="paypalEnrol()">{{ 'core.courses.sendpaymentbutton' | translate }}</button>
|
||||
|
@ -40,12 +40,11 @@
|
|||
<ion-item *ngIf="!isEnrolled && !selfEnrolInstances.length && !paypalEnabled">
|
||||
<p>{{ 'core.courses.notenrollable' | translate }}</p>
|
||||
</ion-item>
|
||||
<!-- @todo: Prefetch course.
|
||||
<a class="item item-icon-left" ng-if="handlersShouldBeShown" ng-click="prefetchCourse()">
|
||||
<i ng-if="prefetchCourseIcon != 'spinner'" class="icon {{prefetchCourseIcon}}"></i>
|
||||
<ion-spinner ng-if="prefetchCourseIcon == 'spinner'" class="icon"></ion-spinner>
|
||||
<a ion-item *ngIf="handlersShouldBeShown" (click)="prefetchCourse()" detail-none>
|
||||
<ion-icon *ngIf="prefetchCourseData.prefetchCourseIcon != 'spinner'" [name]="prefetchCourseData.prefetchCourseIcon" item-start></ion-icon>
|
||||
<ion-spinner *ngIf="prefetchCourseData.prefetchCourseIcon == 'spinner'" item-start></ion-spinner>
|
||||
<h2>{{ 'core.course.downloadcourse' | translate }}</h2>
|
||||
</a> -->
|
||||
</a>
|
||||
<a ion-item (click)="openCourse()" [title]="course.fullname" *ngIf="handlersShouldBeShown">
|
||||
<ion-icon name="briefcase" item-start></ion-icon>
|
||||
<h2>{{ 'core.course.contents' | translate }}</h2>
|
||||
|
|
|
@ -22,6 +22,8 @@ import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
|
|||
import { CoreTextUtilsProvider } from '../../../../providers/utils/text';
|
||||
import { CoreCoursesProvider } from '../../providers/courses';
|
||||
import { CoreCoursesDelegate } from '../../providers/delegate';
|
||||
import { CoreCourseProvider } from '../../../course/providers/course';
|
||||
import { CoreCourseHelperProvider } from '../../../course/providers/helper';
|
||||
|
||||
/**
|
||||
* Page that allows "previewing" a course and enrolling in it if enabled and not enrolled.
|
||||
|
@ -40,7 +42,9 @@ export class CoreCoursesCoursePreviewPage implements OnDestroy {
|
|||
selfEnrolInstances: any[] = [];
|
||||
paypalEnabled: boolean;
|
||||
dataLoaded: boolean;
|
||||
prefetchCourseIcon: string;
|
||||
prefetchCourseData = {
|
||||
prefetchCourseIcon: 'spinner'
|
||||
};
|
||||
|
||||
protected guestWSAvailable: boolean;
|
||||
protected isGuestEnabled: boolean = false;
|
||||
|
@ -55,15 +59,24 @@ export class CoreCoursesCoursePreviewPage implements OnDestroy {
|
|||
protected selfEnrolModal: Modal;
|
||||
protected pageDestroyed = false;
|
||||
protected currentInstanceId: number;
|
||||
protected courseStatusObserver;
|
||||
|
||||
constructor(private navCtrl: NavController, navParams: NavParams, private sitesProvider: CoreSitesProvider,
|
||||
private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, appProvider: CoreAppProvider,
|
||||
private coursesProvider: CoreCoursesProvider, private platform: Platform, private modalCtrl: ModalController,
|
||||
private translate: TranslateService, private eventsProvider: CoreEventsProvider,
|
||||
private coursesDelegate: CoreCoursesDelegate) {
|
||||
private coursesDelegate: CoreCoursesDelegate, private courseHelper: CoreCourseHelperProvider,
|
||||
private courseProvider: CoreCourseProvider) {
|
||||
this.course = navParams.get('course');
|
||||
this.isMobile = appProvider.isMobile();
|
||||
this.isDesktop = appProvider.isDesktop();
|
||||
|
||||
// Listen for status change in course.
|
||||
this.courseStatusObserver = eventsProvider.on(CoreEventsProvider.COURSE_STATUS_CHANGED, (data) => {
|
||||
if (data.courseId == this.course.id) {
|
||||
this.prefetchCourseData.prefetchCourseIcon = this.courseHelper.getCourseStatusIconFromStatus(data.status);
|
||||
}
|
||||
}, sitesProvider.getCurrentSiteId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,7 +101,26 @@ export class CoreCoursesCoursePreviewPage implements OnDestroy {
|
|||
});
|
||||
|
||||
this.getCourse().finally(() => {
|
||||
// @todo: Prefetch course.
|
||||
// Determine course prefetch icon.
|
||||
this.courseHelper.getCourseStatusIcon(this.course.id).then((icon) => {
|
||||
this.prefetchCourseData.prefetchCourseIcon = icon;
|
||||
|
||||
if (icon == 'spinner') {
|
||||
// Course is being downloaded. Get the download promise.
|
||||
let promise = this.courseHelper.getCourseDownloadPromise(this.course.id);
|
||||
if (promise) {
|
||||
// There is a download promise. If it fails, show an error.
|
||||
promise.catch((error) => {
|
||||
if (!this.pageDestroyed) {
|
||||
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// No download, this probably means that the app was closed while downloading. Set previous status.
|
||||
this.courseProvider.setCoursePreviousStatus(this.course.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -97,6 +129,10 @@ export class CoreCoursesCoursePreviewPage implements OnDestroy {
|
|||
*/
|
||||
ngOnDestroy() {
|
||||
this.pageDestroyed = true;
|
||||
|
||||
if (this.courseStatusObserver) {
|
||||
this.courseStatusObserver.off();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,4 +423,16 @@ export class CoreCoursesCoursePreviewPage implements OnDestroy {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch the course.
|
||||
*/
|
||||
prefetchCourse() {
|
||||
this.courseHelper.confirmAndPrefetchCourse(this.prefetchCourseData, this.course, undefined, this.course._handlers)
|
||||
.catch((error) => {
|
||||
if (!this.pageDestroyed) {
|
||||
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<ion-icon name="search"></ion-icon>
|
||||
</button>
|
||||
<core-context-menu>
|
||||
<core-context-menu-item [hidden]="!courses || courses.length < 2" [priority]="800" [content]="'core.courses.downloadcourses' | translate" (action)="prefetchCourses()" [iconAction]="prefetchCoursesData.icon" [closeOnClick]="false" [badge]="prefetchCoursesData.badge"></core-context-menu-item>
|
||||
<core-context-menu-item [hidden]="!courses || courses.length <= 5" [priority]="700" [content]="'core.courses.filtermycourses' | translate" (action)="switchFilter()" [iconAction]="'funnel'"></core-context-menu-item>
|
||||
</core-context-menu>
|
||||
</ion-buttons>
|
||||
|
|
|
@ -18,6 +18,7 @@ import { CoreEventsProvider } from '../../../../providers/events';
|
|||
import { CoreSitesProvider } from '../../../../providers/sites';
|
||||
import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
|
||||
import { CoreCoursesProvider } from '../../providers/courses';
|
||||
import { CoreCourseHelperProvider } from '../../../course/providers/helper';
|
||||
|
||||
/**
|
||||
* Page that displays the list of courses the user is enrolled in.
|
||||
|
@ -34,14 +35,16 @@ export class CoreCoursesMyCoursesPage implements OnDestroy {
|
|||
filter = '';
|
||||
showFilter = false;
|
||||
coursesLoaded = false;
|
||||
prefetchCoursesData: any = {};
|
||||
|
||||
protected prefetchIconInitialized = false;
|
||||
protected myCoursesObserver;
|
||||
protected siteUpdatedObserver;
|
||||
protected isDestroyed = false;
|
||||
|
||||
constructor(private navCtrl: NavController, private coursesProvider: CoreCoursesProvider,
|
||||
private domUtils: CoreDomUtilsProvider, private eventsProvider: CoreEventsProvider,
|
||||
private sitesProvider: CoreSitesProvider) {}
|
||||
private sitesProvider: CoreSitesProvider, private courseHelper: CoreCourseHelperProvider) {}
|
||||
|
||||
/**
|
||||
* View loaded.
|
||||
|
@ -81,7 +84,7 @@ export class CoreCoursesMyCoursesPage implements OnDestroy {
|
|||
this.filteredCourses = this.courses;
|
||||
this.filter = '';
|
||||
|
||||
// this.initPrefetchCoursesIcon();
|
||||
this.initPrefetchCoursesIcon();
|
||||
});
|
||||
}).catch((error) => {
|
||||
this.domUtils.showErrorModalDefault(error, 'core.courses.errorloadcourses', true);
|
||||
|
@ -139,10 +142,60 @@ export class CoreCoursesMyCoursesPage implements OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch all the courses.
|
||||
*/
|
||||
prefetchCourses() {
|
||||
let initialIcon = this.prefetchCoursesData.icon;
|
||||
|
||||
this.prefetchCoursesData.icon = 'spinner';
|
||||
this.prefetchCoursesData.badge = '';
|
||||
return this.courseHelper.confirmAndPrefetchCourses(this.courses, (progress) => {
|
||||
this.prefetchCoursesData.badge = progress.count + ' / ' + progress.total;
|
||||
}).then((downloaded) => {
|
||||
this.prefetchCoursesData.icon = downloaded ? 'ion-android-refresh' : initialIcon;
|
||||
}, (error) => {
|
||||
if (!this.isDestroyed) {
|
||||
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
this.prefetchCoursesData.icon = initialIcon;
|
||||
}
|
||||
}).finally(() => {
|
||||
this.prefetchCoursesData.badge = '';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the prefetch icon for the list of courses.
|
||||
*/
|
||||
protected initPrefetchCoursesIcon() {
|
||||
if (this.prefetchIconInitialized) {
|
||||
// Already initialized.
|
||||
return;
|
||||
}
|
||||
|
||||
this.prefetchIconInitialized = true;
|
||||
|
||||
if (!this.courses || this.courses.length < 2) {
|
||||
// Not enough courses.
|
||||
this.prefetchCoursesData.icon = '';
|
||||
return;
|
||||
}
|
||||
|
||||
this.courseHelper.determineCoursesStatus(this.courses).then((status) => {
|
||||
let icon = this.courseHelper.getCourseStatusIconFromStatus(status);
|
||||
if (icon == 'spinner') {
|
||||
// It seems all courses are being downloaded, show a download button instead.
|
||||
icon = 'cloud-download';
|
||||
}
|
||||
this.prefetchCoursesData.icon = icon;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Page destroyed.
|
||||
*/
|
||||
ngOnDestroy() {
|
||||
this.isDestroyed = true;
|
||||
this.myCoursesObserver && this.myCoursesObserver.off();
|
||||
this.siteUpdatedObserver && this.siteUpdatedObserver.off();
|
||||
}
|
||||
|
|
|
@ -46,22 +46,30 @@
|
|||
<!-- Courses tab. -->
|
||||
<core-tab [title]="'core.courses.courses' | translate" (ionSelect)="tabChanged('courses')">
|
||||
<core-loading [hideUntil]="courses.loaded" class="core-loading-center">
|
||||
<!-- "Time" selector. -->
|
||||
<div no-padding class="clearfix" [hidden]="showFilter">
|
||||
<ion-select [title]="'core.show' | translate" [(ngModel)]="courses.selected" float-start (ngModelChange)="selectedChanged()">
|
||||
<ion-option value="inprogress">{{ 'core.courses.inprogress' | translate }}</ion-option>
|
||||
<ion-option value="future">{{ 'core.courses.future' | translate }}</ion-option>
|
||||
<ion-option value="past">{{ 'core.courses.past' | translate }}</ion-option>
|
||||
</ion-select>
|
||||
<button [hidden]="!courses[courses.selected] || !courses[courses.selected].length" ion-button icon-only clear color="dark" float-end>
|
||||
<ion-icon name="cloud-download"></ion-icon>
|
||||
</button>
|
||||
<!-- Download all courses. -->
|
||||
<div *ngIf="courses[courses.selected] && courses[courses.selected].length > 1">
|
||||
<button *ngIf="prefetchCoursesData[courses.selected].icon && prefetchCoursesData[courses.selected].icon != 'spinner'" ion-button icon-only clear color="dark" float-end (click)="prefetchCourses()">
|
||||
<ion-icon [name]="prefetchCoursesData[courses.selected].icon"></ion-icon>
|
||||
</button>
|
||||
<ion-spinner *ngIf="!prefetchCoursesData[courses.selected].icon || prefetchCoursesData[courses.selected].icon == 'spinner'" float-end></ion-spinner>
|
||||
<span float-end *ngIf="prefetchCoursesData[courses.selected].badge">{{prefetchCoursesData[courses.selected].badge}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Filter courses. -->
|
||||
<div no-padding padding-bottom [hidden]="!showFilter">
|
||||
<ion-item>
|
||||
<ion-label><ion-icon name="funnel" class="placeholder-icon"></ion-icon></ion-label>
|
||||
<ion-input type="text" name="filter" clearInput [(ngModel)]="courses.filter" (ngModelChange)="filterChanged($event)" [placeholder]="'core.courses.filtermycourses' | translate"></ion-input>
|
||||
</ion-item>
|
||||
</div>
|
||||
<!-- List of courses. -->
|
||||
<div>
|
||||
<ion-grid no-padding>
|
||||
<ion-row no-padding>
|
||||
|
|
|
@ -12,11 +12,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnDestroy } from '@angular/core';
|
||||
import { IonicPage, NavController } from 'ionic-angular';
|
||||
import { CoreDomUtilsProvider } from '../../../../providers/utils/dom';
|
||||
import { CoreCoursesProvider } from '../../providers/courses';
|
||||
import { CoreCoursesMyOverviewProvider } from '../../providers/my-overview';
|
||||
import { CoreCourseHelperProvider } from '../../../course/providers/helper';
|
||||
import * as moment from 'moment';
|
||||
|
||||
/**
|
||||
|
@ -27,7 +28,7 @@ import * as moment from 'moment';
|
|||
selector: 'page-core-courses-my-overview',
|
||||
templateUrl: 'my-overview.html',
|
||||
})
|
||||
export class CoreCoursesMyOverviewPage {
|
||||
export class CoreCoursesMyOverviewPage implements OnDestroy {
|
||||
tabShown = 'courses';
|
||||
timeline = {
|
||||
sort: 'sortbydates',
|
||||
|
@ -52,21 +53,24 @@ export class CoreCoursesMyOverviewPage {
|
|||
searchEnabled: boolean;
|
||||
filteredCourses: any[];
|
||||
tabs = [];
|
||||
prefetchCoursesData = {
|
||||
inprogress: {},
|
||||
past: {},
|
||||
future: {}
|
||||
};
|
||||
|
||||
protected prefetchIconInitialized = false;
|
||||
protected myCoursesObserver;
|
||||
protected siteUpdatedObserver;
|
||||
protected prefetchIconsInitialized = false;
|
||||
protected isDestroyed;
|
||||
|
||||
constructor(private navCtrl: NavController, private coursesProvider: CoreCoursesProvider,
|
||||
private domUtils: CoreDomUtilsProvider, private myOverviewProvider: CoreCoursesMyOverviewProvider) {}
|
||||
private domUtils: CoreDomUtilsProvider, private myOverviewProvider: CoreCoursesMyOverviewProvider,
|
||||
private courseHelper: CoreCourseHelperProvider) {}
|
||||
|
||||
/**
|
||||
* View loaded.
|
||||
*/
|
||||
ionViewDidLoad() {
|
||||
this.searchEnabled = !this.coursesProvider.isSearchCoursesDisabledInSite();
|
||||
|
||||
// @todo: Course download.
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,6 +148,8 @@ export class CoreCoursesMyOverviewPage {
|
|||
this.courses.filter = '';
|
||||
this.showFilter = false;
|
||||
this.filteredCourses = this.courses[this.courses.selected];
|
||||
|
||||
this.initPrefetchCoursesIcons();
|
||||
}).catch((error) => {
|
||||
this.domUtils.showErrorModalDefault(error, 'Error getting my overview data.');
|
||||
});
|
||||
|
@ -229,6 +235,7 @@ export class CoreCoursesMyOverviewPage {
|
|||
}
|
||||
break;
|
||||
case 'courses':
|
||||
this.prefetchIconsInitialized = false;
|
||||
return this.fetchMyOverviewCourses();
|
||||
}
|
||||
}).finally(() => {
|
||||
|
@ -315,4 +322,65 @@ export class CoreCoursesMyOverviewPage {
|
|||
selectedChanged() {
|
||||
this.filteredCourses = this.courses[this.courses.selected];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefetch all the shown courses.
|
||||
*/
|
||||
prefetchCourses() {
|
||||
let selected = this.courses.selected,
|
||||
selectedData = this.prefetchCoursesData[selected],
|
||||
initialIcon = selectedData.icon;
|
||||
|
||||
selectedData.icon = 'spinner';
|
||||
selectedData.badge = '';
|
||||
return this.courseHelper.confirmAndPrefetchCourses(this.courses[selected], (progress) => {
|
||||
selectedData.badge = progress.count + ' / ' + progress.total;
|
||||
}).then((downloaded) => {
|
||||
selectedData.icon = downloaded ? 'refresh' : initialIcon;
|
||||
}, (error) => {
|
||||
if (!this.isDestroyed) {
|
||||
this.domUtils.showErrorModalDefault(error, 'core.course.errordownloadingcourse', true);
|
||||
selectedData.icon = initialIcon;
|
||||
}
|
||||
}).finally(() => {
|
||||
selectedData.badge = '';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the prefetch icon for selected courses.
|
||||
*/
|
||||
protected initPrefetchCoursesIcons() {
|
||||
if (this.prefetchIconsInitialized) {
|
||||
// Already initialized.
|
||||
return;
|
||||
}
|
||||
|
||||
this.prefetchIconsInitialized = true;
|
||||
|
||||
Object.keys(this.prefetchCoursesData).forEach((filter) => {
|
||||
if (!this.courses[filter] || this.courses[filter].length < 2) {
|
||||
// Not enough courses.
|
||||
this.prefetchCoursesData[filter].icon = '';
|
||||
return;
|
||||
}
|
||||
|
||||
this.courseHelper.determineCoursesStatus(this.courses[filter]).then((status) => {
|
||||
let icon = this.courseHelper.getCourseStatusIconFromStatus(status);
|
||||
if (icon == 'spinner') {
|
||||
// It seems all courses are being downloaded, show a download button instead.
|
||||
icon = 'cloud-download';
|
||||
}
|
||||
this.prefetchCoursesData[filter].icon = icon;
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being destroyed.
|
||||
*/
|
||||
ngOnDestroy() {
|
||||
this.isDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue