MOBILE-2921 enrol: Support enrolment expiry push clicks

main
Dani Palou 2019-03-19 08:19:16 +01:00
parent a38fcf6d6f
commit e8ab5edc2a
7 changed files with 145 additions and 25 deletions

View File

@ -303,10 +303,10 @@ export class CoreCourseSectionPage implements OnDestroy {
// Load the course format options when course completion is enabled to show completion progress on sections.
if (this.course.enablecompletion && this.coursesProvider.isGetCoursesByFieldAvailable()) {
promises.push(this.coursesProvider.getCoursesByField('id', this.course.id).catch(() => {
promises.push(this.coursesProvider.getCourseByField('id', this.course.id).catch(() => {
// Ignore errors.
}).then((courses) => {
courses && courses[0] && Object.assign(this.course, courses[0]);
}).then((course) => {
course && Object.assign(this.course, course);
if (this.course.courseformatoptions) {
this.course.courseformatoptions = this.utils.objectToKeyValueMap(this.course.courseformatoptions,

View File

@ -113,10 +113,10 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler {
return sections[0];
} else {
// Try to retrieve the marker.
promise = this.coursesProvider.getCoursesByField('id', course.id).catch(() => {
promise = this.coursesProvider.getCourseByField('id', course.id).catch(() => {
// Ignore errors.
}).then((courses) => {
return courses && courses[0] && courses[0].marker;
}).then((course) => {
return course && course.marker;
});
}
@ -156,10 +156,14 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler {
*
* @param {NavController} navCtrl The NavController instance to use.
* @param {any} course The course to open. It should contain a "format" attribute.
* @param {any} [params] Params to pass to the course page.
* @return {Promise<any>} Promise resolved when done.
*/
openCourse(navCtrl: NavController, course: any): Promise<any> {
return navCtrl.push('CoreCourseSectionPage', { course: course });
openCourse(navCtrl: NavController, course: any, params?: any): Promise<any> {
params = params || {};
Object.assign(params, { course: course });
return navCtrl.push('CoreCourseSectionPage', params);
}
/**

View File

@ -92,9 +92,10 @@ export interface CoreCourseFormatHandler extends CoreDelegateHandler {
*
* @param {NavController} navCtrl The NavController instance to use.
* @param {any} course The course to open. It should contain a "format" attribute.
* @param {any} [params] Params to pass to the course page.
* @return {Promise<any>} Promise resolved when done.
*/
openCourse?(navCtrl: NavController, course: any): Promise<any>;
openCourse?(navCtrl: NavController, course: any, params?: any): Promise<any>;
/**
* Return the Component to use to display the course format instead of using the default one.
@ -337,10 +338,11 @@ export class CoreCourseFormatDelegate extends CoreDelegate {
*
* @param {NavController} navCtrl The NavController instance to use.
* @param {any} course The course to open. It should contain a "format" attribute.
* @param {any} [params] Params to pass to the course page.
* @return {Promise<any>} Promise resolved when done.
*/
openCourse(navCtrl: NavController, course: any): Promise<any> {
return this.executeFunctionOnEnabled(course.format, 'openCourse', [navCtrl, course]);
openCourse(navCtrl: NavController, course: any, params?: any): Promise<any> {
return this.executeFunctionOnEnabled(course.format, 'openCourse', [navCtrl, course, params]);
}
/**

View File

@ -1401,22 +1401,35 @@ export class CoreCourseHelperProvider {
*
* @param {NavController} navCtrl The nav controller to use.
* @param {any} course Course to open
* @param {any} [params] Params to pass to the course page.
* @return {Promise<any>} Promise resolved when done.
*/
openCourse(navCtrl: NavController, course: any): void {
openCourse(navCtrl: NavController, course: any, params?: any): Promise<any> {
if (this.sitePluginsProvider.sitePluginPromiseExists('format_' + course.format)) {
// This course uses a custom format plugin, wait for the format plugin to finish loading.
const loading = this.domUtils.showModalLoading();
this.sitePluginsProvider.sitePluginLoaded('format_' + course.format).then(() => {
return this.sitePluginsProvider.sitePluginLoaded('format_' + course.format).then(() => {
// The format loaded successfully, but the handlers wont be registered until all site plugins have loaded.
if (this.sitePluginsProvider.sitePluginsFinishedLoading) {
loading.dismiss();
this.courseFormatDelegate.openCourse(navCtrl, course);
return this.courseFormatDelegate.openCourse(navCtrl, course, params);
} else {
const observer = this.eventsProvider.on(CoreEventsProvider.SITE_PLUGINS_LOADED, () => {
loading.dismiss();
this.courseFormatDelegate.openCourse(navCtrl, course);
observer && observer.off();
});
// Wait for plugins to be loaded.
const deferred = this.utils.promiseDefer(),
observer = this.eventsProvider.on(CoreEventsProvider.SITE_PLUGINS_LOADED, () => {
loading.dismiss();
observer && observer.off();
this.courseFormatDelegate.openCourse(navCtrl, course, params).then((response) => {
deferred.resolve(response);
}).catch((error) => {
deferred.reject(error);
});
});
return deferred.promise;
}
}).catch(() => {
// The site plugin failed to load. The user needs to restart the app to try loading it again.
@ -1425,7 +1438,7 @@ export class CoreCourseHelperProvider {
});
} else {
// No custom format plugin. We don't need to wait for anything.
this.courseFormatDelegate.openCourse(navCtrl, course);
return this.courseFormatDelegate.openCourse(navCtrl, course, params);
}
}
}

View File

@ -20,8 +20,10 @@ import { CoreCoursesDashboardProvider } from './providers/dashboard';
import { CoreCoursesCourseLinkHandler } from './providers/course-link-handler';
import { CoreCoursesIndexLinkHandler } from './providers/courses-index-link-handler';
import { CoreCoursesDashboardLinkHandler } from './providers/dashboard-link-handler';
import { CoreCoursesEnrolPushClickHandler } from './providers/enrol-push-click-handler';
import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate';
import { CoreContentLinksDelegate } from '@core/contentlinks/providers/delegate';
import { CorePushNotificationsDelegate } from '@core/pushnotifications/providers/delegate';
// List of providers (without handlers).
export const CORE_COURSES_PROVIDERS: any[] = [
@ -41,18 +43,21 @@ export const CORE_COURSES_PROVIDERS: any[] = [
CoreDashboardMainMenuHandler,
CoreCoursesCourseLinkHandler,
CoreCoursesIndexLinkHandler,
CoreCoursesDashboardLinkHandler
CoreCoursesDashboardLinkHandler,
CoreCoursesEnrolPushClickHandler
],
exports: []
})
export class CoreCoursesModule {
constructor(mainMenuDelegate: CoreMainMenuDelegate, contentLinksDelegate: CoreContentLinksDelegate,
mainMenuHandler: CoreDashboardMainMenuHandler, courseLinkHandler: CoreCoursesCourseLinkHandler,
indexLinkHandler: CoreCoursesIndexLinkHandler, dashboardLinkHandler: CoreCoursesDashboardLinkHandler) {
indexLinkHandler: CoreCoursesIndexLinkHandler, dashboardLinkHandler: CoreCoursesDashboardLinkHandler,
pushNotificationsDelegate: CorePushNotificationsDelegate, pushClickHandler: CoreCoursesEnrolPushClickHandler) {
mainMenuDelegate.registerHandler(mainMenuHandler);
contentLinksDelegate.registerHandler(courseLinkHandler);
contentLinksDelegate.registerHandler(indexLinkHandler);
contentLinksDelegate.registerHandler(dashboardLinkHandler);
pushNotificationsDelegate.registerClickHandler(pushClickHandler);
}
}

View File

@ -0,0 +1,79 @@
// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CorePushNotificationsClickHandler } from '@core/pushnotifications/providers/delegate';
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreLoginHelperProvider } from '@core/login/providers/helper';
/**
* Handler for enrol push notifications clicks.
*/
@Injectable()
export class CoreCoursesEnrolPushClickHandler implements CorePushNotificationsClickHandler {
name = 'CoreCoursesEnrolPushClickHandler';
priority = 200;
constructor(private utils: CoreUtilsProvider, private domUtils: CoreDomUtilsProvider,
private courseHelper: CoreCourseHelperProvider, private loginHelper: CoreLoginHelperProvider) {}
/**
* Check if a notification click is handled by this handler.
*
* @param {any} notification The notification to check.
* @return {boolean} Whether the notification click is handled by this handler
*/
handles(notification: any): boolean | Promise<boolean> {
return this.utils.isTrueOrOne(notification.notif) && notification.moodlecomponent.indexOf('enrol_') === 0 &&
notification.name == 'expiry_notification';
}
/**
* Handle the notification click.
*
* @param {any} notification The notification to check.
* @return {Promise<any>} Promise resolved when done.
*/
handleClick(notification: any): Promise<any> {
const courseId = Number(notification.courseid),
modal = this.domUtils.showModalLoading();
return this.courseHelper.getCourse(courseId, notification.site).then((result) => {
const params: any = {
course: result.course
};
let page;
if (notification.contexturl && notification.contexturl.indexOf('user/index.php') != -1) {
// Open the participants tab.
page = 'CoreCourseSectionPage';
params.selectedTab = 'CoreUserParticipants';
} else if (result.enrolled) {
// User is still enrolled, open the course.
page = 'CoreCourseSectionPage';
} else {
// User not enrolled anymore, open the preview page.
page = 'CoreCoursesCoursePreviewPage';
}
return this.loginHelper.redirect(page, params, notification.site);
}).catch((error) => {
this.domUtils.showErrorModalDefault(error, 'Error getting course.');
}).finally(() => {
modal.dismiss();
});
}
}

View File

@ -13,9 +13,11 @@
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler';
import { CoreContentLinksAction } from '@core/contentlinks/providers/delegate';
import { CoreLoginHelperProvider } from '@core/login/providers/helper';
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreUserProvider } from './user';
/**
@ -27,7 +29,8 @@ export class CoreUserParticipantsLinkHandler extends CoreContentLinksHandlerBase
featureName = 'CoreCourseOptionsDelegate_CoreUserParticipants';
pattern = /\/user\/index\.php/;
constructor(private userProvider: CoreUserProvider, private loginHelper: CoreLoginHelperProvider) {
constructor(private userProvider: CoreUserProvider, private loginHelper: CoreLoginHelperProvider,
private courseHelper: CoreCourseHelperProvider, private domUtils: CoreDomUtilsProvider) {
super();
}
@ -46,8 +49,22 @@ export class CoreUserParticipantsLinkHandler extends CoreContentLinksHandlerBase
return [{
action: (siteId, navCtrl?): void => {
// Always use redirect to make it the new history root (to avoid "loops" in history).
this.loginHelper.redirect('CoreUserParticipantsPage', {courseId: courseId}, siteId);
const modal = this.domUtils.showModalLoading();
this.courseHelper.getCourse(courseId, siteId).then((result) => {
const params: any = {
course: result.course,
selectedTab: 'CoreUserParticipants'
};
// Always use redirect to make it the new history root (to avoid "loops" in history).
return this.loginHelper.redirect('CoreCourseSectionPage', params, siteId);
}).catch(() => {
// Cannot get course for some reason, just open the participants page.
this.loginHelper.redirect('CoreUserParticipantsPage', {courseId: courseId}, siteId);
}).finally(() => {
modal.dismiss();
});
}
}];
}