From 138f83d97952d248a20415927b555fcb33eb0c67 Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Wed, 14 Feb 2018 12:46:40 +0100 Subject: [PATCH] MOBILE-2325 badges: Show new page in user profile --- src/addon/badges/badges.module.ts | 34 +++++++ src/addon/badges/lang/en.json | 13 +++ src/addon/badges/providers/badges.ts | 110 +++++++++++++++++++++ src/addon/badges/providers/user-handler.ts | 75 ++++++++++++++ src/app/app.module.ts | 4 +- src/core/user/providers/user-handler.ts | 4 +- 6 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 src/addon/badges/badges.module.ts create mode 100644 src/addon/badges/lang/en.json create mode 100644 src/addon/badges/providers/badges.ts create mode 100644 src/addon/badges/providers/user-handler.ts diff --git a/src/addon/badges/badges.module.ts b/src/addon/badges/badges.module.ts new file mode 100644 index 000000000..51a2f2c31 --- /dev/null +++ b/src/addon/badges/badges.module.ts @@ -0,0 +1,34 @@ +// (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 { NgModule } from '@angular/core'; +import { AddonBadgesProvider } from './providers/badges'; +import { AddonBadgesUserHandler } from './providers/user-handler'; +import { CoreUserDelegate } from '../../core/user/providers/user-delegate'; + +@NgModule({ + declarations: [ + ], + imports: [ + ], + providers: [ + AddonBadgesProvider, + AddonBadgesUserHandler + ] +}) +export class AddonBadgesModule { + constructor(userDelegate: CoreUserDelegate, userHandler: AddonBadgesUserHandler) { + userDelegate.registerHandler(userHandler); + } +} diff --git a/src/addon/badges/lang/en.json b/src/addon/badges/lang/en.json new file mode 100644 index 000000000..4443773c4 --- /dev/null +++ b/src/addon/badges/lang/en.json @@ -0,0 +1,13 @@ +{ + "badgedetails": "Badge details", + "badges": "Badges", + "contact": "Contact", + "dateawarded": "Date issued", + "expired": "Expired", + "expirydate": "Expiry date", + "issuancedetails": "Badge expiry", + "issuerdetails": "Issuer details", + "issuername": "Issuer name", + "nobadges": "There are no badges available.", + "recipientdetails": "Recipient details" +} diff --git a/src/addon/badges/providers/badges.ts b/src/addon/badges/providers/badges.ts new file mode 100644 index 000000000..b27802e9d --- /dev/null +++ b/src/addon/badges/providers/badges.ts @@ -0,0 +1,110 @@ +// (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 { CoreLoggerProvider } from '../../../providers/logger'; +import { CoreSitesProvider } from '../../../providers/sites'; + +/** + * Service to handle badges. + */ +@Injectable() +export class AddonBadgesProvider { + protected logger; + protected ROOT_CACHE_KEY = 'mmaBadges:'; + + constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider) { + this.logger = logger.getInstance('AddonBadgesProvider'); + } + + /** + * Returns whether or not the badge plugin is enabled for a certain site. + * + * This method is called quite often and thus should only perform a quick + * check, we should not be calling WS from here. + * + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if enabled, false otherwise. + */ + isPluginEnabled(siteId?: string): Promise { + + return this.sitesProvider.getSite(siteId).then((site) => { + if (!site.canUseAdvancedFeature('enablebadges')) { + return false; + } else if (!site.wsAvailable('core_course_get_user_navigation_options')) { + return false; + } + + return true; + }); + } + + /** + * Get the cache key for the get badges call. + * + * @param {number} courseId ID of the course to get the badges from. + * @param {number} userId ID of the user to get the badges from. + * @return {string} Cache key. + */ + protected getBadgesCacheKey(courseId: number, userId: number): string { + return this.ROOT_CACHE_KEY + 'badges:' + courseId + ':' + userId; + } + + /** + * Get issued badges for a certain user in a course. + * + * @param {number} courseId ID of the course to get the badges from. + * @param {number} userId ID of the user to get the badges from. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise}Promise to be resolved when the badges are retrieved. + */ + getUserBadges(courseId: number, userId: number, siteId?: string): Promise { + + this.logger.debug('Get badges for course ' + courseId); + + return this.sitesProvider.getSite(siteId).then((site) => { + + const data = { + courseid : courseId, + userid : userId + }, + presets = { + cacheKey: this.getBadgesCacheKey(courseId, userId) + }; + + return site.read('core_badges_get_user_badges', data, presets).then((response) => { + if (response && response.badges) { + return response.badges; + } else { + return Promise.reject(null); + } + }); + }); + } + + /** + * Invalidate get badges WS call. + * + * @param {number} courseId Course ID. + * @param {number} userId ID of the user to get the badges from. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved when data is invalidated. + */ + invalidateUserBadges(courseId: number, userId: number, siteId?: string): Promise { + + return this.sitesProvider.getSite(siteId).then((site) => { + return site.invalidateWsCacheForKey(this.getBadgesCacheKey(courseId, userId)); + }); + } +} diff --git a/src/addon/badges/providers/user-handler.ts b/src/addon/badges/providers/user-handler.ts new file mode 100644 index 000000000..12bd8ee95 --- /dev/null +++ b/src/addon/badges/providers/user-handler.ts @@ -0,0 +1,75 @@ +// (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 { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '../../../core/user/providers/user-delegate'; +import { AddonBadgesProvider } from './badges'; + +/** + * Profile badges handler. + */ +@Injectable() +export class AddonBadgesUserHandler implements CoreUserProfileHandler { + name = 'mmaBadges'; + priority = 50; + type = CoreUserDelegate.TYPE_NEW_PAGE; + + constructor(protected badgesProvider: AddonBadgesProvider) { } + + /** + * Check if handler is enabled. + * + * @return {Promise} Always enabled. + */ + isEnabled(): Promise { + return this.badgesProvider.isPluginEnabled(); + } + + /** + * Check if handler is enabled for this user in this context. + * + * @param {any} user User to check. + * @param {number} courseId Course ID. + * @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions. + * @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions. + * @return {boolean} True if enabled, false otherwise. + */ + isEnabledForUser(user: any, courseId: number, navOptions?: any, admOptions?: any): boolean { + + if (navOptions && typeof navOptions.badges != 'undefined') { + return navOptions.badges; + } + + // If we reach here, it means we are opening the user site profile. + return true; + } + + /** + * Returns the data needed to render the handler. + * + * @return {CoreUserProfileHandlerData} Data needed to render the handler. + */ + getDisplayData(user: any, courseId: number): CoreUserProfileHandlerData { + return { + icon: 'ion-trophy', + title: 'addon.badges.badges', + class: '', + action: (event, navCtrl, user, courseId): void => { + event.preventDefault(); + event.stopPropagation(); + //navCtrl.push(); + } + }; + } +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 1ae090cd9..eaf546c1a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -69,8 +69,9 @@ import { CoreSitePluginsModule } from '@core/siteplugins/siteplugins.module'; import { CoreCompileModule } from '@core/compile/compile.module'; // Addon modules. +import { AddonBadgesModule } from '@addon/badges/badges.module'; import { AddonCalendarModule } from '@addon/calendar/calendar.module'; -import { AddonCompetencyModule } from '../addon/competency/competency.module'; +import { AddonCompetencyModule } from '@addon/competency/competency.module'; import { AddonUserProfileFieldModule } from '@addon/userprofilefield/userprofilefield.module'; import { AddonFilesModule } from '@addon/files/files.module'; import { AddonModBookModule } from '@addon/mod/book/book.module'; @@ -150,6 +151,7 @@ export const CORE_PROVIDERS: any[] = [ CoreSettingsModule, CoreSitePluginsModule, CoreCompileModule, + AddonBadgesModule, AddonCalendarModule, AddonCompetencyModule, AddonUserProfileFieldModule, diff --git a/src/core/user/providers/user-handler.ts b/src/core/user/providers/user-handler.ts index 5ddb638b2..7414dd287 100644 --- a/src/core/user/providers/user-handler.ts +++ b/src/core/user/providers/user-handler.ts @@ -41,8 +41,8 @@ export class CoreUserProfileMailHandler implements CoreUserProfileHandler { * * @param {any} user User to check. * @param {number} courseId Course ID. - * @param {any} [navOptions] Course navigation options for current user. See $mmCourses#getUserNavigationOptions. - * @param {any} [admOptions] Course admin options for current user. See $mmCourses#getUserAdministrationOptions. + * @param {any} [navOptions] Course navigation options for current user. See CoreCoursesProvider.getUserNavigationOptions. + * @param {any} [admOptions] Course admin options for current user. See CoreCoursesProvider.getUserAdministrationOptions. * @return {boolean|Promise} Promise resolved with true if enabled, resolved with false otherwise. */ isEnabledForUser(user: any, courseId: number, navOptions?: any, admOptions?: any): boolean | Promise {