diff --git a/src/addon/mod/lesson/lesson.module.ts b/src/addon/mod/lesson/lesson.module.ts index caad60d06..0c1e194ec 100644 --- a/src/addon/mod/lesson/lesson.module.ts +++ b/src/addon/mod/lesson/lesson.module.ts @@ -17,6 +17,7 @@ import { CoreCronDelegate } from '@providers/cron'; import { CoreCourseModuleDelegate } from '@core/course/providers/module-delegate'; import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate'; import { CoreContentLinksDelegate } from '@core/contentlinks/providers/delegate'; +import { CorePushNotificationsDelegate } from '@core/pushnotifications/providers/delegate'; import { AddonModLessonComponentsModule } from './components/components.module'; import { AddonModLessonProvider } from './providers/lesson'; import { AddonModLessonOfflineProvider } from './providers/lesson-offline'; @@ -29,6 +30,7 @@ import { AddonModLessonIndexLinkHandler } from './providers/index-link-handler'; import { AddonModLessonGradeLinkHandler } from './providers/grade-link-handler'; import { AddonModLessonReportLinkHandler } from './providers/report-link-handler'; import { AddonModLessonListLinkHandler } from './providers/list-link-handler'; +import { AddonModLessonPushClickHandler } from './providers/push-click-handler'; import { CoreUpdateManagerProvider } from '@providers/update-manager'; // List of providers (without handlers). @@ -56,7 +58,8 @@ export const ADDON_MOD_LESSON_PROVIDERS: any[] = [ AddonModLessonIndexLinkHandler, AddonModLessonGradeLinkHandler, AddonModLessonReportLinkHandler, - AddonModLessonListLinkHandler + AddonModLessonListLinkHandler, + AddonModLessonPushClickHandler ] }) export class AddonModLessonModule { @@ -65,7 +68,8 @@ export class AddonModLessonModule { cronDelegate: CoreCronDelegate, syncHandler: AddonModLessonSyncCronHandler, linksDelegate: CoreContentLinksDelegate, indexHandler: AddonModLessonIndexLinkHandler, gradeHandler: AddonModLessonGradeLinkHandler, reportHandler: AddonModLessonReportLinkHandler, updateManager: CoreUpdateManagerProvider, - listLinkHandler: AddonModLessonListLinkHandler) { + listLinkHandler: AddonModLessonListLinkHandler, pushNotificationsDelegate: CorePushNotificationsDelegate, + pushClickHandler: AddonModLessonPushClickHandler) { moduleDelegate.registerHandler(moduleHandler); prefetchDelegate.registerHandler(prefetchHandler); @@ -74,6 +78,7 @@ export class AddonModLessonModule { linksDelegate.registerHandler(gradeHandler); linksDelegate.registerHandler(reportHandler); linksDelegate.registerHandler(listLinkHandler); + pushNotificationsDelegate.registerClickHandler(pushClickHandler); // Allow migrating the tables from the old app to the new schema. updateManager.registerSiteTablesMigration([ diff --git a/src/addon/mod/lesson/providers/push-click-handler.ts b/src/addon/mod/lesson/providers/push-click-handler.ts new file mode 100644 index 000000000..841298c52 --- /dev/null +++ b/src/addon/mod/lesson/providers/push-click-handler.ts @@ -0,0 +1,117 @@ +// (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 { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CorePushNotificationsClickHandler } from '@core/pushnotifications/providers/delegate'; +import { CoreLoginHelperProvider } from '@core/login/providers/helper'; +import { CoreCourseHelperProvider } from '@core/course/providers/helper'; +import { CoreGradesProvider } from '@core/grades/providers/grades'; +import { AddonModLessonProvider } from './lesson'; + +/** + * Handler for lesson push notifications clicks. + */ +@Injectable() +export class AddonModLessonPushClickHandler implements CorePushNotificationsClickHandler { + name = 'AddonModLessonPushClickHandler'; + priority = 200; + featureName = 'CoreCourseModuleDelegate_AddonModLesson'; + + constructor(private utils: CoreUtilsProvider, private lessonProvider: AddonModLessonProvider, + private loginHelper: CoreLoginHelperProvider, private domUtils: CoreDomUtilsProvider, + private courseHelper: CoreCourseHelperProvider, private gradesProvider: CoreGradesProvider) {} + + /** + * 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 { + if (this.utils.isTrueOrOne(notification.notif) && notification.moodlecomponent == 'mod_lesson' && + notification.name == 'graded_essay') { + + return this.lessonProvider.isPluginEnabled(notification.site); + } + + return false; + } + + /** + * Handle the notification click. + * + * @param {any} notification The notification to check. + * @return {Promise} Promise resolved when done. + */ + handleClick(notification: any): Promise { + const data = notification.customdata || {}, + courseId = Number(notification.courseid), + moduleId = Number(data.cmid), + modal = this.domUtils.showModalLoading(); + let promise; + + if (moduleId) { + // Try to open the module grade directly. Check if it's possible. + promise = this.gradesProvider.isGradeItemsAvalaible(notification.site).catch(() => { + return false; + }); + } else { + promise = Promise.resolve(false); + } + + return promise.then((getGrades) => { + + if (getGrades) { + return this.gradesProvider.getGradeItems(courseId, undefined, undefined, notification.site).then((items) => { + // Find the item of th module. + const item = items.find((item) => { + return moduleId == item.cmid; + }); + + if (item) { + // Open the item directly. + const pageParams: any = { + courseId: courseId, + gradeId: item.id + }; + + this.loginHelper.redirect('CoreGradesGradePage', pageParams, notification.site); + } + + return Promise.reject(null); + }); + } else { + return Promise.reject(null); + } + + }).catch(() => { + // Cannot get grade items or there's no need to. Open the course with the grades tab selected. + return this.courseHelper.getCourse(courseId, notification.site).then((result) => { + const pageParams: any = { + course: result.course, + selectedTab: 'CoreGrades' + }; + + this.loginHelper.redirect('CoreCourseSectionPage', pageParams, notification.site); + }); + }).catch(() => { + // Cannot get course for some reason, just open the grades page. + return this.loginHelper.redirect('CoreGradesCoursePage', {course: {id: courseId}}, notification.site); + }).finally(() => { + modal.dismiss(); + }); + } +} diff --git a/src/core/grades/providers/user-link-handler.ts b/src/core/grades/providers/user-link-handler.ts index 91e0d4f19..62ff332d6 100644 --- a/src/core/grades/providers/user-link-handler.ts +++ b/src/core/grades/providers/user-link-handler.ts @@ -15,7 +15,10 @@ import { Injectable } from '@angular/core'; import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler'; import { CoreContentLinksAction } from '@core/contentlinks/providers/delegate'; +import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper'; +import { CoreLoginHelperProvider } from '@core/login/providers/helper'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreGradesProvider } from './grades'; /** @@ -26,7 +29,9 @@ export class CoreGradesUserLinkHandler extends CoreContentLinksHandlerBase { name = 'CoreGradesUserLinkHandler'; pattern = /\/grade\/report\/user\/index.php/; - constructor(private linkHelper: CoreContentLinksHelperProvider, private gradesProvider: CoreGradesProvider) { + constructor(private linkHelper: CoreContentLinksHelperProvider, private gradesProvider: CoreGradesProvider, + private domUtils: CoreDomUtilsProvider, private courseHelper: CoreCourseHelperProvider, + private loginHelper: CoreLoginHelperProvider) { super(); } @@ -41,14 +46,39 @@ export class CoreGradesUserLinkHandler extends CoreContentLinksHandlerBase { */ getActions(siteIds: string[], url: string, params: any, courseId?: number): CoreContentLinksAction[] | Promise { + courseId = courseId || params.id; + return [{ action: (siteId, navCtrl?): void => { - const pageParams = { - course: {id: courseId}, - userId: params.userid ? parseInt(params.userid, 10) : false, - }; - // Always use redirect to make it the new history root (to avoid "loops" in history). - this.linkHelper.goInSite(navCtrl, 'CoreGradesCoursePage', pageParams, siteId); + const userId = params.userid ? parseInt(params.userid, 10) : false; + + if (userId) { + // Open the grades page directly. + const pageParams = { + course: {id: courseId}, + userId: userId, + }; + + this.linkHelper.goInSite(navCtrl, 'CoreGradesCoursePage', pageParams, siteId); + } else { + // No userid, open the course with the grades tab selected. + const modal = this.domUtils.showModalLoading(); + + this.courseHelper.getCourse(courseId, siteId).then((result) => { + const pageParams: any = { + course: result.course, + selectedTab: 'CoreGrades' + }; + + // Use redirect to prevent loops in the navigation. + return this.loginHelper.redirect('CoreCourseSectionPage', pageParams, siteId); + }).catch(() => { + // Cannot get course for some reason, just open the grades page. + return this.linkHelper.goInSite(navCtrl, 'CoreGradesCoursePage', {course: {id: courseId}}, siteId); + }).finally(() => { + modal.dismiss(); + }); + } } }]; } @@ -64,10 +94,10 @@ export class CoreGradesUserLinkHandler extends CoreContentLinksHandlerBase { * @return {boolean|Promise} Whether the handler is enabled for the URL and site. */ isEnabled(siteId: string, url: string, params: any, courseId?: number): boolean | Promise { - if (!courseId) { + if (!courseId && !params.id) { return false; } - return this.gradesProvider.isPluginEnabledForCourse(courseId, siteId); + return this.gradesProvider.isPluginEnabledForCourse(courseId || params.id, siteId); } } diff --git a/src/core/login/providers/helper.ts b/src/core/login/providers/helper.ts index 3d84c5232..21154313c 100644 --- a/src/core/login/providers/helper.ts +++ b/src/core/login/providers/helper.ts @@ -591,26 +591,28 @@ export class CoreLoginHelperProvider { * @param {string} page Name of the page to load. * @param {any} params Params to pass to the page. * @param {string} siteId Site to load. + * @return {Promise} Promise resolved when done. */ - protected loadSiteAndPage(page: string, params: any, siteId: string): void { + protected loadSiteAndPage(page: string, params: any, siteId: string): Promise { const navCtrl = this.appProvider.getRootNavController(); if (siteId == CoreConstants.NO_SITE_ID) { // Page doesn't belong to a site, just load the page. - navCtrl.setRoot(page, params); + return navCtrl.setRoot(page, params); } else { const modal = this.domUtils.showModalLoading(); - this.sitesProvider.loadSite(siteId, page, params).then((loggedIn) => { + + return this.sitesProvider.loadSite(siteId, page, params).then((loggedIn) => { if (loggedIn) { // Due to DeepLinker, we need to remove the path from the URL before going to main menu. // IonTabs checks the URL to determine which path to load for deep linking, so we clear the URL. this.location.replaceState(''); - navCtrl.setRoot('CoreMainMenuPage', { redirectPage: page, redirectParams: params }); + return navCtrl.setRoot('CoreMainMenuPage', { redirectPage: page, redirectParams: params }); } }).catch((error) => { // Site doesn't exist. - navCtrl.setRoot('CoreLoginSitesPage'); + return navCtrl.setRoot('CoreLoginSitesPage'); }).finally(() => { modal.dismiss(); }); @@ -794,8 +796,9 @@ export class CoreLoginHelperProvider { * @param {string} page Name of the page to load. * @param {any} params Params to pass to the page. * @param {string} [siteId] Site to load. If not defined, current site. + * @return {Promise} Promise resolved when done. */ - redirect(page: string, params?: any, siteId?: string): void { + redirect(page: string, params?: any, siteId?: string): Promise { siteId = siteId || this.sitesProvider.getCurrentSiteId(); if (this.sitesProvider.isLoggedIn()) { @@ -804,10 +807,11 @@ export class CoreLoginHelperProvider { if (this.sitePluginsProvider.hasSitePluginsLoaded) { // The site has site plugins so the app will be restarted. Store the data and logout. this.appProvider.storeRedirect(siteId, page, params); - this.sitesProvider.logout(); + + return this.sitesProvider.logout(); } else { - this.sitesProvider.logout().then(() => { - this.loadSiteAndPage(page, params, siteId); + return this.sitesProvider.logout().then(() => { + return this.loadSiteAndPage(page, params, siteId); }); } } else { @@ -815,11 +819,13 @@ export class CoreLoginHelperProvider { } } else { if (siteId) { - this.loadSiteAndPage(page, params, siteId); + return this.loadSiteAndPage(page, params, siteId); } else { - this.appProvider.getRootNavController().setRoot('CoreLoginSitesPage'); + return this.appProvider.getRootNavController().setRoot('CoreLoginSitesPage'); } } + + return Promise.resolve(); } /** diff --git a/src/core/user/providers/participants-link-handler.ts b/src/core/user/providers/participants-link-handler.ts index 1a219a754..b9bb3eddd 100644 --- a/src/core/user/providers/participants-link-handler.ts +++ b/src/core/user/providers/participants-link-handler.ts @@ -18,6 +18,7 @@ import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-han import { CoreContentLinksAction } from '@core/contentlinks/providers/delegate'; import { CoreLoginHelperProvider } from '@core/login/providers/helper'; import { CoreCourseHelperProvider } from '@core/course/providers/helper'; +import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper'; import { CoreUserProvider } from './user'; /** @@ -30,7 +31,8 @@ export class CoreUserParticipantsLinkHandler extends CoreContentLinksHandlerBase pattern = /\/user\/index\.php/; constructor(private userProvider: CoreUserProvider, private loginHelper: CoreLoginHelperProvider, - private courseHelper: CoreCourseHelperProvider, private domUtils: CoreDomUtilsProvider) { + private courseHelper: CoreCourseHelperProvider, private domUtils: CoreDomUtilsProvider, + private linkHelper: CoreContentLinksHelperProvider) { super(); } @@ -61,7 +63,7 @@ export class CoreUserParticipantsLinkHandler extends CoreContentLinksHandlerBase 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); + return this.linkHelper.goInSite(navCtrl, 'CoreUserParticipantsPage', {courseId: courseId}, siteId); }).finally(() => { modal.dismiss(); });