Merge pull request #2007 from dpalou/MOBILE-3055

Mobile 3055
main
Juan Leyva 2019-07-25 20:49:56 +02:00 committed by GitHub
commit 1147269cf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 189 additions and 23 deletions

View File

@ -552,16 +552,12 @@ export class CoreCourseOptionsDelegate extends CoreDelegate {
/**
* Update handlers for each course.
*
* @param {string} [siteId] Site ID.
*/
updateData(siteId?: string): void {
if (this.sitesProvider.getCurrentSiteId() === siteId) {
// Update handlers for all courses.
for (const courseId in this.coursesHandlers) {
const handler = this.coursesHandlers[courseId];
this.updateHandlersForCourse(parseInt(courseId, 10), handler.access, handler.navOptions, handler.admOptions);
}
updateData(): void {
// Update handlers for all courses.
for (const courseId in this.coursesHandlers) {
const handler = this.coursesHandlers[courseId];
this.updateHandlersForCourse(parseInt(courseId, 10), handler.access, handler.navOptions, handler.admOptions);
}
}

View File

@ -13,6 +13,7 @@
// limitations under the License.
import { Injectable } from '@angular/core';
import { CoreEventsProvider } from '@providers/events';
import { CoreLoggerProvider } from '@providers/logger';
import { CoreSitesProvider } from '@providers/sites';
import { CoreSite } from '@classes/site';
@ -24,13 +25,16 @@ import { CoreSite } from '@classes/site';
export class CoreCoursesProvider {
static SEARCH_PER_PAGE = 20;
static ENROL_INVALID_KEY = 'CoreCoursesEnrolInvalidKey';
static EVENT_MY_COURSES_UPDATED = 'courses_my_courses_updated';
static EVENT_MY_COURSES_CHANGED = 'courses_my_courses_changed'; // User course list changed while app is running.
static EVENT_MY_COURSES_UPDATED = 'courses_my_courses_updated'; // A course was hidden/favourite, or user enroled in a course.
static EVENT_MY_COURSES_REFRESHED = 'courses_my_courses_refreshed';
static EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED = 'dashboard_download_enabled_changed';
protected ROOT_CACHE_KEY = 'mmCourses:';
protected logger;
protected userCoursesIds: {[id: number]: boolean}; // Use an object to make it faster to search.
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider) {
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private eventsProvider: CoreEventsProvider) {
this.logger = logger.getInstance('CoreCoursesProvider');
}
@ -743,7 +747,53 @@ export class CoreCoursesProvider {
data.returnusercount = 0;
}
return site.read('core_enrol_get_users_courses', data, preSets);
return site.read('core_enrol_get_users_courses', data, preSets).then((courses) => {
if (this.userCoursesIds) {
// Check if the list of courses has changed.
const added = [],
removed = [],
previousIds = Object.keys(this.userCoursesIds),
currentIds = {}; // Use an object to make it faster to search.
courses.forEach((course) => {
currentIds[course.id] = true;
if (!this.userCoursesIds[course.id]) {
// Course added.
added.push(course.id);
}
});
if (courses.length - added.length != previousIds.length) {
// A course was removed, check which one.
previousIds.forEach((id) => {
if (!currentIds[id]) {
// Course removed.
removed.push(Number(id));
}
});
}
if (added.length || removed.length) {
// At least 1 course was added or removed, trigger the event.
this.eventsProvider.trigger(CoreCoursesProvider.EVENT_MY_COURSES_CHANGED, {
added: added,
removed: removed
}, site.getId());
}
this.userCoursesIds = currentIds;
} else {
this.userCoursesIds = {};
// Store the list of courses.
courses.forEach((course) => {
this.userCoursesIds[course.id] = true;
});
}
return courses;
});
});
}

View File

@ -19,6 +19,7 @@ import {
} from '@core/course/providers/options-delegate';
import { CoreSitePluginsBaseHandler } from './base-handler';
import { CoreSitePluginsCourseOptionComponent } from '../../components/course-option/course-option';
import { CoreUtilsProvider, PromiseDefer } from '@providers/utils/utils';
/**
* Handler to display a site plugin in course options.
@ -27,8 +28,11 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl
priority: number;
isMenuHandler: boolean;
protected updatingDefer: PromiseDefer;
constructor(name: string, protected title: string, protected plugin: any, protected handlerSchema: any,
protected initResult: any, protected sitePluginsProvider: CoreSitePluginsProvider) {
protected initResult: any, protected sitePluginsProvider: CoreSitePluginsProvider,
protected utils: CoreUtilsProvider) {
super(name);
this.priority = handlerSchema.priority;
@ -45,8 +49,13 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl
* @return {boolean|Promise<boolean>} True or promise resolved with true if enabled.
*/
isEnabledForCourse(courseId: number, accessData: any, navOptions?: any, admOptions?: any): boolean | Promise<boolean> {
return this.sitePluginsProvider.isHandlerEnabledForCourse(
courseId, this.handlerSchema.restricttoenrolledcourses, this.initResult.restrict);
// Wait for "init" result to be updated.
const promise = this.updatingDefer ? this.updatingDefer.promise : Promise.resolve();
return promise.then(() => {
return this.sitePluginsProvider.isHandlerEnabledForCourse(
courseId, this.handlerSchema.restricttoenrolledcourses, this.initResult.restrict);
});
}
/**
@ -108,4 +117,23 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl
return this.sitePluginsProvider.prefetchFunctions(component, args, this.handlerSchema, course.id, undefined, true);
}
/**
* Set init result.
*
* @param {any} result Result to set.
*/
setInitResult(result: any): void {
this.initResult = result;
this.updatingDefer.resolve();
delete this.updatingDefer;
}
/**
* Mark init being updated.
*/
updatingInit(): void {
this.updatingDefer = this.utils.promiseDefer();
}
}

View File

@ -16,6 +16,7 @@ import { NavController } from 'ionic-angular';
import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate';
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
import { CoreSitePluginsBaseHandler } from './base-handler';
import { CoreUtilsProvider, PromiseDefer } from '@providers/utils/utils';
/**
* Handler to display a site plugin in the user profile.
@ -37,8 +38,11 @@ export class CoreSitePluginsUserProfileHandler extends CoreSitePluginsBaseHandle
*/
type: string;
protected updatingDefer: PromiseDefer;
constructor(name: string, protected title: string, protected plugin: any, protected handlerSchema: any,
protected initResult: any, protected sitePluginsProvider: CoreSitePluginsProvider) {
protected initResult: any, protected sitePluginsProvider: CoreSitePluginsProvider,
protected utils: CoreUtilsProvider) {
super(name);
this.priority = handlerSchema.priority;
@ -97,4 +101,23 @@ export class CoreSitePluginsUserProfileHandler extends CoreSitePluginsBaseHandle
}
};
}
/**
* Set init result.
*
* @param {any} result Result to set.
*/
setInitResult(result: any): void {
this.initResult = result;
this.updatingDefer.resolve();
delete this.updatingDefer;
}
/**
* Mark init being updated.
*/
updatingInit(): void {
this.updatingDefer = this.utils.promiseDefer();
}
}

View File

@ -30,6 +30,7 @@ import { CoreSitePluginsProvider } from './siteplugins';
import { CoreCompileProvider } from '@core/compile/providers/compile';
import { CoreQuestionProvider } from '@core/question/providers/question';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCoursesProvider } from '@core/courses/providers/courses';
// Delegates
import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate';
@ -79,13 +80,14 @@ import { CoreSitePluginsBlockHandler } from '@core/siteplugins/classes/handlers/
@Injectable()
export class CoreSitePluginsHelperProvider {
protected logger;
protected courseRestrictHandlers = {};
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
private mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate,
private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider, private http: Http,
private sitePluginsProvider: CoreSitePluginsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate,
private compileProvider: CoreCompileProvider, private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider,
private courseOptionsDelegate: CoreCourseOptionsDelegate, eventsProvider: CoreEventsProvider,
private courseOptionsDelegate: CoreCourseOptionsDelegate, private eventsProvider: CoreEventsProvider,
private courseFormatDelegate: CoreCourseFormatDelegate, private profileFieldDelegate: CoreUserProfileFieldDelegate,
private textUtils: CoreTextUtilsProvider, private filepoolProvider: CoreFilepoolProvider,
private settingsDelegate: CoreSettingsDelegate, private questionDelegate: CoreQuestionDelegate,
@ -122,6 +124,13 @@ export class CoreSitePluginsHelperProvider {
window.location.reload();
}
});
// Re-load plugins restricted for courses when the list of user courses changes.
eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_CHANGED, (data) => {
if (data && data.siteId && data.siteId == this.sitesProvider.getCurrentSiteId() && data.added && data.added.length) {
this.reloadCourseRestrictHandlers();
}
});
}
/**
@ -375,6 +384,7 @@ export class CoreSitePluginsHelperProvider {
*/
loadSitePlugins(plugins: any[]): Promise<any> {
const promises = [];
this.courseRestrictHandlers = {};
plugins.forEach((plugin) => {
const pluginPromise = this.loadSitePlugin(plugin);
@ -683,10 +693,21 @@ export class CoreSitePluginsHelperProvider {
// Create and register the handler.
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title);
prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title),
handler = new CoreSitePluginsCourseOptionHandler(uniqueName, prefixedTitle, plugin,
handlerSchema, initResult, this.sitePluginsProvider, this.utils);
this.courseOptionsDelegate.registerHandler(new CoreSitePluginsCourseOptionHandler(uniqueName, prefixedTitle, plugin,
handlerSchema, initResult, this.sitePluginsProvider));
this.courseOptionsDelegate.registerHandler(handler);
if (initResult && initResult.restrict && initResult.restrict.courses) {
// This handler is restricted to certan courses, store it in the list.
this.courseRestrictHandlers[uniqueName] = {
plugin: plugin,
handlerName: handlerName,
handlerSchema: handlerSchema,
handler: handler
};
}
return uniqueName;
}
@ -889,10 +910,21 @@ export class CoreSitePluginsHelperProvider {
// Create and register the handler.
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title);
prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title),
handler = new CoreSitePluginsUserProfileHandler(uniqueName, prefixedTitle, plugin, handlerSchema,
initResult, this.sitePluginsProvider, this.utils);
this.userDelegate.registerHandler(new CoreSitePluginsUserProfileHandler(uniqueName, prefixedTitle, plugin, handlerSchema,
initResult, this.sitePluginsProvider));
this.userDelegate.registerHandler(handler);
if (initResult && initResult.restrict && initResult.restrict.courses) {
// This handler is restricted to certan courses, store it in the list.
this.courseRestrictHandlers[uniqueName] = {
plugin: plugin,
handlerName: handlerName,
handlerSchema: handlerSchema,
handler: handler
};
}
return uniqueName;
}
@ -935,4 +967,40 @@ export class CoreSitePluginsHelperProvider {
return new CoreSitePluginsWorkshopAssessmentStrategyHandler(uniqueName, strategyName);
});
}
/**
* Reload the handlers that are restricted to certain courses.
*
* @return {Promise<any>} Promise resolved when done.
*/
protected reloadCourseRestrictHandlers(): Promise<any> {
if (!Object.keys(this.courseRestrictHandlers).length) {
// No course restrict handlers, nothing to do.
return Promise.resolve();
}
const promises = [];
for (const name in this.courseRestrictHandlers) {
const data = this.courseRestrictHandlers[name];
if (!data.handler || !data.handler.setInitResult) {
// No handler or it doesn't implement a required function, ignore it.
continue;
}
// Mark the handler as being updated.
data.handler.updatingInit && data.handler.updatingInit();
promises.push(this.executeHandlerInit(data.plugin, data.handlerSchema).then((initResult) => {
data.handler.setInitResult(initResult);
}).catch((error) => {
this.logger.error('Error reloading course restrict handler', error, data.plugin);
}));
}
return Promise.all(promises).then(() => {
this.eventsProvider.trigger(CoreEventsProvider.SITE_PLUGINS_COURSE_RESTRICT_UPDATED, {});
});
}
}

View File

@ -48,6 +48,7 @@ export class CoreEventsProvider {
static COURSE_STATUS_CHANGED = 'course_status_changed';
static SECTION_STATUS_CHANGED = 'section_status_changed';
static SITE_PLUGINS_LOADED = 'site_plugins_loaded';
static SITE_PLUGINS_COURSE_RESTRICT_UPDATED = 'site_plugins_course_restrict_updated';
static LOGIN_SITE_CHECKED = 'login_site_checked';
static LOGIN_SITE_UNCHECKED = 'login_site_unchecked';
static IAB_LOAD_START = 'inappbrowser_load_start';