From 1c0a86d045a14439c42d390d34912bc988e24606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Mon, 27 Sep 2021 16:46:43 +0200 Subject: [PATCH] MOBILE-2748 icon: Make getModuleIconSrc async --- .../activitymodules/activitymodules.ts | 4 +- .../services/recentlyaccesseditems.ts | 6 +- .../timeline/components/events/events.ts | 14 ++--- .../calendar/components/calendar/calendar.ts | 57 ++++++++++--------- .../upcoming-events/upcoming-events.ts | 2 +- src/addons/calendar/pages/day/day.page.ts | 2 +- src/addons/calendar/pages/event/event.page.ts | 2 +- .../calendar/services/calendar-helper.ts | 6 +- .../mod/forum/services/handlers/module.ts | 4 +- .../mod/label/services/handlers/module.ts | 2 +- .../mod/lti/services/handlers/module.ts | 6 +- .../mod/resource/services/handlers/module.ts | 8 +-- .../mod/url/services/handlers/module.ts | 8 +-- .../course/classes/module-base-handler.ts | 6 +- .../course/pages/contents/contents.ts | 8 +-- .../features/course/services/course-helper.ts | 10 ++-- src/core/features/course/services/course.ts | 8 +-- .../services/handlers/default-module.ts | 6 +- .../course/services/module-delegate.ts | 20 +++---- .../features/grades/services/grades-helper.ts | 26 ++++----- .../features/sitehome/pages/index/index.ts | 32 +++++------ .../features/sitehome/services/sitehome.ts | 3 +- 22 files changed, 123 insertions(+), 117 deletions(-) diff --git a/src/addons/block/activitymodules/components/activitymodules/activitymodules.ts b/src/addons/block/activitymodules/components/activitymodules/activitymodules.ts index c377040b5..fdeb9a967 100644 --- a/src/addons/block/activitymodules/components/activitymodules/activitymodules.ts +++ b/src/addons/block/activitymodules/components/activitymodules/activitymodules.ts @@ -99,9 +99,9 @@ export class AddonBlockActivityModulesComponent extends CoreBlockBaseComponent i let icon: string; if (modName === 'resources') { - icon = CoreCourse.getModuleIconSrc('page', modIcons['page']); + icon = await CoreCourse.getModuleIconSrc('page', modIcons['page']); } else { - icon = CoreCourseModuleDelegate.getModuleIconSrc(modName, modIcons[modName]) || ''; + icon = await CoreCourseModuleDelegate.getModuleIconSrc(modName, modIcons[modName]); } this.entries.push({ diff --git a/src/addons/block/recentlyaccesseditems/services/recentlyaccesseditems.ts b/src/addons/block/recentlyaccesseditems/services/recentlyaccesseditems.ts index f2b50bc92..8261f24d3 100644 --- a/src/addons/block/recentlyaccesseditems/services/recentlyaccesseditems.ts +++ b/src/addons/block/recentlyaccesseditems/services/recentlyaccesseditems.ts @@ -52,14 +52,14 @@ export class AddonBlockRecentlyAccessedItemsProvider { const items: AddonBlockRecentlyAccessedItemsItem[] = await site.read('block_recentlyaccesseditems_get_recent_items', undefined, preSets); - return items.map((item) => { + return await Promise.all(items.map(async (item) => { const modicon = item.icon && CoreDomUtils.getHTMLElementAttribute(item.icon, 'src'); - item.iconUrl = CoreCourse.getModuleIconSrc(item.modname, modicon || undefined); + item.iconUrl = await CoreCourse.getModuleIconSrc(item.modname, modicon || undefined); item.iconTitle = item.icon && CoreDomUtils.getHTMLElementAttribute(item.icon, 'title'); return item; - }); + })); } /** diff --git a/src/addons/block/timeline/components/events/events.ts b/src/addons/block/timeline/components/events/events.ts index f4266f50c..bf77da586 100644 --- a/src/addons/block/timeline/components/events/events.ts +++ b/src/addons/block/timeline/components/events/events.ts @@ -51,12 +51,12 @@ export class AddonBlockTimelineEventsComponent implements OnChanges { /** * Detect changes on input properties. */ - ngOnChanges(changes: {[name: string]: SimpleChange}): void { + async ngOnChanges(changes: {[name: string]: SimpleChange}): Promise { this.showCourse = CoreUtils.isTrueOrOne(this.showCourse); if (changes.events || changes.from || changes.to) { if (this.events && this.events.length > 0) { - const filteredEvents = this.filterEventsByTime(this.from, this.to); + const filteredEvents = await this.filterEventsByTime(this.from, this.to); this.empty = !filteredEvents || filteredEvents.length <= 0; const eventsByDay: Record = {}; @@ -92,22 +92,22 @@ export class AddonBlockTimelineEventsComponent implements OnChanges { * @param end Number of days after the start. * @return Filtered events. */ - protected filterEventsByTime(start: number, end?: number): AddonBlockTimelineEvent[] { + protected async filterEventsByTime(start: number, end?: number): Promise { start = moment().add(start, 'days').startOf('day').unix(); end = typeof end != 'undefined' ? moment().add(end, 'days').startOf('day').unix() : end; - return this.events.filter((event) => { + return await Promise.all(this.events.filter((event) => { if (end) { return start <= event.timesort && event.timesort < end; } return start <= event.timesort; - }).map((event) => { - event.iconUrl = CoreCourse.getModuleIconSrc(event.icon.component); + }).map(async (event) => { + event.iconUrl = await CoreCourse.getModuleIconSrc(event.icon.component); event.iconTitle = event.modulename && CoreCourse.translateModuleName(event.modulename); return event; - }); + })); } /** diff --git a/src/addons/calendar/components/calendar/calendar.ts b/src/addons/calendar/components/calendar/calendar.ts index c6e97072a..5575e917c 100644 --- a/src/addons/calendar/components/calendar/calendar.ts +++ b/src/addons/calendar/components/calendar/calendar.ts @@ -68,8 +68,8 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro isCurrentMonth = false; isPastMonth = false; - protected year?: number; - protected month?: number; + protected year: number; + protected month: number; protected categoriesRetrieved = false; protected categories: { [id: number]: CoreCategoryData } = {}; protected currentSiteId: string; @@ -121,16 +121,19 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro ); this.differ = differs.find([]).create(); + + const now = new Date(); + + this.year = now.getFullYear(); + this.month = now.getMonth() + 1; } /** * Component loaded. */ ngOnInit(): void { - const now = new Date(); - - this.year = this.initialYear ? this.initialYear : now.getFullYear(); - this.month = this.initialMonth ? this.initialMonth : now.getMonth() + 1; + this.year = this.initialYear ? this.initialYear : this.year; + this.month = this.initialMonth ? this.initialMonth : this.month; this.calculateIsCurrentMonth(); @@ -211,11 +214,11 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro // Don't pass courseId and categoryId, we'll filter them locally. let result: { daynames: Partial[]; weeks: Partial[] }; try { - result = await AddonCalendar.getMonthlyEvents(this.year!, this.month!); + result = await AddonCalendar.getMonthlyEvents(this.year, this.month); } catch (error) { if (!CoreApp.isOnline()) { // Allow navigating to non-cached months in offline (behave as if using emergency cache). - result = await AddonCalendarHelper.getOfflineMonthWeeks(this.year!, this.month!); + result = await AddonCalendarHelper.getOfflineMonthWeeks(this.year, this.month); } else { throw error; } @@ -223,27 +226,29 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro // Calculate the period name. We don't use the one in result because it's in server's language. this.periodName = CoreTimeUtils.userDate( - new Date(this.year!, this.month! - 1).getTime(), + new Date(this.year, this.month - 1).getTime(), 'core.strftimemonthyear', ); this.weekDays = AddonCalendar.getWeekDays(result.daynames[0].dayno); this.weeks = result.weeks as AddonCalendarWeek[]; this.calculateIsCurrentMonth(); - this.weeks.forEach((week) => { - week.days.forEach((day) => { + await Promise.all(this.weeks.map(async (week) => { + await Promise.all(week.days.map(async (day) => { day.periodName = CoreTimeUtils.userDate( - new Date(this.year!, this.month! - 1, day.mday).getTime(), + new Date(this.year, this.month - 1, day.mday).getTime(), 'core.strftimedaydate', ); day.eventsFormated = day.eventsFormated || []; day.filteredEvents = day.filteredEvents || []; - day.events.forEach((event) => { - /// Format online events. - day.eventsFormated!.push(AddonCalendarHelper.formatEventData(event)); - }); - }); - }); + // Format online events. + const onlineEventsFormatted = await Promise.all( + day.events.map(async (event) => AddonCalendarHelper.formatEventData(event)), + ); + + day.eventsFormated = day.eventsFormated.concat(onlineEventsFormatted); + })); + })); if (this.isCurrentMonth) { const currentDay = new Date().getDate(); @@ -323,7 +328,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro // Don't invalidate monthly events after a change, it has already been handled. if (!afterChange) { - promises.push(AddonCalendar.invalidateMonthlyEvents(this.year!, this.month!)); + promises.push(AddonCalendar.invalidateMonthlyEvents(this.year, this.month)); } promises.push(CoreCourses.invalidateCategories(0, true)); promises.push(AddonCalendar.invalidateTimeFormat()); @@ -386,7 +391,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro * @param day Day. */ dayClicked(day: number): void { - this.onDayClicked.emit({ day: day, month: this.month!, year: this.year! }); + this.onDayClicked.emit({ day: day, month: this.month, year: this.year }); } /** @@ -398,7 +403,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro this.currentTime = CoreTimeUtils.timestamp(); this.isCurrentMonth = this.year == now.getFullYear() && this.month == now.getMonth() + 1; - this.isPastMonth = this.year! < now.getFullYear() || (this.year == now.getFullYear() && this.month! < now.getMonth() + 1); + this.isPastMonth = this.year < now.getFullYear() || (this.year == now.getFullYear() && this.month < now.getMonth() + 1); } /** @@ -432,9 +437,9 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro protected decreaseMonth(): void { if (this.month === 1) { this.month = 12; - this.year!--; + this.year--; } else { - this.month!--; + this.month--; } } @@ -444,9 +449,9 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro protected increaseMonth(): void { if (this.month === 12) { this.month = 1; - this.year!++; + this.year++; } else { - this.month!++; + this.month++; } } @@ -455,7 +460,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro */ protected mergeEvents(): void { const monthOfflineEvents: { [day: number]: AddonCalendarEventToDisplay[] } = - this.offlineEvents[AddonCalendarHelper.getMonthId(this.year!, this.month!)]; + this.offlineEvents[AddonCalendarHelper.getMonthId(this.year, this.month)]; this.weeks.forEach((week) => { week.days.forEach((day) => { diff --git a/src/addons/calendar/components/upcoming-events/upcoming-events.ts b/src/addons/calendar/components/upcoming-events/upcoming-events.ts index ae0448d60..7566c6d14 100644 --- a/src/addons/calendar/components/upcoming-events/upcoming-events.ts +++ b/src/addons/calendar/components/upcoming-events/upcoming-events.ts @@ -173,7 +173,7 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On async fetchEvents(): Promise { // Don't pass courseId and categoryId, we'll filter them locally. const result = await AddonCalendar.getUpcomingEvents(); - this.onlineEvents = result.events.map((event) => AddonCalendarHelper.formatEventData(event)); + this.onlineEvents = await Promise.all(result.events.map((event) => AddonCalendarHelper.formatEventData(event))); // Schedule notifications for the events retrieved. AddonCalendar.scheduleEventsNotifications(this.onlineEvents); // Merge the online events with offline data. diff --git a/src/addons/calendar/pages/day/day.page.ts b/src/addons/calendar/pages/day/day.page.ts index 2d26cf281..f02bc54d1 100644 --- a/src/addons/calendar/pages/day/day.page.ts +++ b/src/addons/calendar/pages/day/day.page.ts @@ -333,7 +333,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { try { // Don't pass courseId and categoryId, we'll filter them locally. result = await AddonCalendar.getDayEvents(this.year, this.month, this.day); - this.onlineEvents = result.events.map((event) => AddonCalendarHelper.formatEventData(event)); + this.onlineEvents = await Promise.all(result.events.map((event) => AddonCalendarHelper.formatEventData(event))); } catch (error) { if (CoreApp.isOnline()) { throw error; diff --git a/src/addons/calendar/pages/event/event.page.ts b/src/addons/calendar/pages/event/event.page.ts index 88d4597f9..9ddc41f58 100644 --- a/src/addons/calendar/pages/event/event.page.ts +++ b/src/addons/calendar/pages/event/event.page.ts @@ -207,7 +207,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { try { // Get the event data. const event = await AddonCalendar.getEventById(this.eventId); - this.event = AddonCalendarHelper.formatEventData(event); + this.event = await AddonCalendarHelper.formatEventData(event); try { const offlineEvent = AddonCalendarHelper.formatOfflineEventData( diff --git a/src/addons/calendar/services/calendar-helper.ts b/src/addons/calendar/services/calendar-helper.ts index d457e4c05..447745701 100644 --- a/src/addons/calendar/services/calendar-helper.ts +++ b/src/addons/calendar/services/calendar-helper.ts @@ -161,7 +161,9 @@ export class AddonCalendarHelperProvider { * * @param event Event to format. */ - formatEventData(event: AddonCalendarEvent | AddonCalendarEventBase | AddonCalendarGetEventsEvent): AddonCalendarEventToDisplay { + async formatEventData( + event: AddonCalendarEvent | AddonCalendarEventBase | AddonCalendarGetEventsEvent, + ): Promise { const eventFormatted: AddonCalendarEventToDisplay = { ...event, @@ -176,7 +178,7 @@ export class AddonCalendarHelperProvider { }; if (event.modulename) { - eventFormatted.eventIcon = CoreCourse.getModuleIconSrc(event.modulename); + eventFormatted.eventIcon = await CoreCourse.getModuleIconSrc(event.modulename); eventFormatted.moduleIcon = eventFormatted.eventIcon; eventFormatted.iconTitle = CoreCourse.translateModuleName(event.modulename); } diff --git a/src/addons/mod/forum/services/handlers/module.ts b/src/addons/mod/forum/services/handlers/module.ts index 3b7327923..7418879ca 100644 --- a/src/addons/mod/forum/services/handlers/module.ts +++ b/src/addons/mod/forum/services/handlers/module.ts @@ -53,8 +53,8 @@ export class AddonModForumModuleHandlerService extends CoreModuleHandlerBase imp /** * @inheritdoc */ - getData(module: CoreCourseAnyModuleData, courseId: number): CoreCourseModuleHandlerData { - const data = super.getData(module, courseId); + async getData(module: CoreCourseAnyModuleData, courseId: number): Promise { + const data = await super.getData(module, courseId); if ('afterlink' in module && !!module.afterlink) { data.extraBadgeColor = ''; diff --git a/src/addons/mod/label/services/handlers/module.ts b/src/addons/mod/label/services/handlers/module.ts index 9fd176d90..c51a15fa0 100644 --- a/src/addons/mod/label/services/handlers/module.ts +++ b/src/addons/mod/label/services/handlers/module.ts @@ -44,7 +44,7 @@ export class AddonModLabelModuleHandlerService extends CoreModuleHandlerBase imp /** * @inheritdoc */ - getData(module: CoreCourseWSModule): CoreCourseModuleHandlerData { + async getData(module: CoreCourseWSModule): Promise { // Remove the description from the module so it isn't rendered twice. const title = module.description || ''; module.description = ''; diff --git a/src/addons/mod/lti/services/handlers/module.ts b/src/addons/mod/lti/services/handlers/module.ts index 6d5e78673..79d1b90a1 100644 --- a/src/addons/mod/lti/services/handlers/module.ts +++ b/src/addons/mod/lti/services/handlers/module.ts @@ -54,13 +54,13 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple /** * @inheritdoc */ - getData( + async getData( module: CoreCourseAnyModuleData, courseId: number, sectionId?: number, forCoursePage?: boolean, - ): CoreCourseModuleHandlerData { - const data = super.getData(module, courseId, sectionId, forCoursePage); + ): Promise { + const data = await super.getData(module, courseId, sectionId, forCoursePage); data.showDownloadButton = false; data.buttons = [{ diff --git a/src/addons/mod/resource/services/handlers/module.ts b/src/addons/mod/resource/services/handlers/module.ts index e2639eeea..f9ed3f2c2 100644 --- a/src/addons/mod/resource/services/handlers/module.ts +++ b/src/addons/mod/resource/services/handlers/module.ts @@ -63,12 +63,12 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase /** * @inheritdoc */ - getData( + async getData( module: CoreCourseAnyModuleData, courseId: number, sectionId?: number, forCoursePage?: boolean, - ): CoreCourseModuleHandlerData { + ): Promise { const updateStatus = (status: string): void => { if (!handlerData.buttons) { return; @@ -79,7 +79,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase }; const openWithPicker = CoreFileHelper.defaultIsOpenWithPicker(); - const handlerData = super.getData(module, courseId, sectionId, forCoursePage); + const handlerData = await super.getData(module, courseId, sectionId, forCoursePage); handlerData.updateStatus = updateStatus.bind(this); handlerData.buttons = [{ hidden: true, @@ -233,7 +233,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase // No previously set, just set the icon. if (resourceData.icon == '') { - resourceData.icon = CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined); + resourceData.icon = await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined); } return resourceData; diff --git a/src/addons/mod/url/services/handlers/module.ts b/src/addons/mod/url/services/handlers/module.ts index bd5f28b2c..94634f181 100644 --- a/src/addons/mod/url/services/handlers/module.ts +++ b/src/addons/mod/url/services/handlers/module.ts @@ -54,7 +54,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple /** * @inheritdoc */ - getData(module: CoreCourseAnyModuleData, courseId: number): CoreCourseModuleHandlerData { + async getData(module: CoreCourseAnyModuleData, courseId: number): Promise { /** * Open the URL. @@ -77,7 +77,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple }; const handlerData: CoreCourseModuleHandlerData = { - icon: CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined), + icon: await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined), title: module.name, class: 'addon-mod_url-handler', showDownloadButton: false, @@ -111,7 +111,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple }], }; - this.hideLinkButton(module, courseId).then((hideButton) => { + this.hideLinkButton(module, courseId).then(async (hideButton) => { if (!handlerData.buttons) { return; } @@ -121,7 +121,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple if (module.contents && module.contents[0]) { // Calculate the icon to use. handlerData.icon = AddonModUrl.guessIcon(module.contents[0].fileurl) || - CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined); + await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined); } return; diff --git a/src/core/features/course/classes/module-base-handler.ts b/src/core/features/course/classes/module-base-handler.ts index 16ab933ed..d44bc8238 100644 --- a/src/core/features/course/classes/module-base-handler.ts +++ b/src/core/features/course/classes/module-base-handler.ts @@ -34,14 +34,14 @@ export class CoreModuleHandlerBase implements Partial { /** * @inheritdoc */ - getData( + async getData( module: CoreCourseAnyModuleData, courseId: number, // eslint-disable-line @typescript-eslint/no-unused-vars sectionId?: number, // eslint-disable-line @typescript-eslint/no-unused-vars forCoursePage?: boolean, // eslint-disable-line @typescript-eslint/no-unused-vars - ): CoreCourseModuleHandlerData { + ): Promise { return { - icon: CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined), + icon: await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined), title: module.name, class: 'addon-mod_' + module.modname + '-handler', showDownloadButton: true, diff --git a/src/core/features/course/pages/contents/contents.ts b/src/core/features/course/pages/contents/contents.ts index 2cccc6ecb..3a95835d6 100644 --- a/src/core/features/course/pages/contents/contents.ts +++ b/src/core/features/course/pages/contents/contents.ts @@ -89,16 +89,16 @@ export class CoreCourseContentsPage implements OnInit, OnDestroy { * Component being initialized. */ async ngOnInit(): Promise { - const course = CoreNavigator.getRouteParam('course'); - if (!course) { - CoreDomUtils.showErrorModal('Missing required course parameter.'); + try { + this.course = CoreNavigator.getRequiredRouteParam('course'); + } catch (error) { + CoreDomUtils.showErrorModal(error); CoreNavigator.back(); return; } - this.course = course; this.sectionId = CoreNavigator.getRouteNumberParam('sectionId'); this.sectionNumber = CoreNavigator.getRouteNumberParam('sectionNumber'); this.moduleId = CoreNavigator.getRouteNumberParam('moduleId'); diff --git a/src/core/features/course/services/course-helper.ts b/src/core/features/course/services/course-helper.ts index 5b322d60d..b87b0ab95 100644 --- a/src/core/features/course/services/course-helper.ts +++ b/src/core/features/course/services/course-helper.ts @@ -190,8 +190,8 @@ export class CoreCourseHelperProvider { hasContent = true; - section.modules.forEach((module) => { - module.handlerData = CoreCourseModuleDelegate.getModuleDataFor( + section.modules.forEach(async (module) => { + module.handlerData = await CoreCourseModuleDelegate.getModuleDataFor( module.modname, module, courseId, @@ -1610,7 +1610,7 @@ export class CoreCourseHelperProvider { if (CoreSites.getCurrentSiteId() == site.getId()) { // Try to use the module's handler to navigate cleanly. - module.handlerData = CoreCourseModuleDelegate.getModuleDataFor( + module.handlerData = await CoreCourseModuleDelegate.getModuleDataFor( module.modname, module, courseId, @@ -1664,9 +1664,9 @@ export class CoreCourseHelperProvider { * @param modParams Params to pass to the module * @param True if module can be opened, false otherwise. */ - openModule(module: CoreCourseModule, courseId: number, sectionId?: number, modParams?: Params): boolean { + async openModule(module: CoreCourseModule, courseId: number, sectionId?: number, modParams?: Params): Promise { if (!module.handlerData) { - module.handlerData = CoreCourseModuleDelegate.getModuleDataFor( + module.handlerData = await CoreCourseModuleDelegate.getModuleDataFor( module.modname, module, courseId, diff --git a/src/core/features/course/services/course.ts b/src/core/features/course/services/course.ts index c714008fa..0e7f38649 100644 --- a/src/core/features/course/services/course.ts +++ b/src/core/features/course/services/course.ts @@ -520,7 +520,7 @@ export class CoreCourseProvider { const params: CoreCourseGetCourseModuleWSParams = { cmid: moduleId, }; - const preSets = { + const preSets: CoreSiteWSPreSets = { cacheKey: this.getModuleCacheKey(moduleId), updateFrequency: CoreSite.FREQUENCY_RARELY, }; @@ -528,11 +528,9 @@ export class CoreCourseProvider { if (response.warnings && response.warnings.length) { throw new CoreWSError(response.warnings[0]); - } else if (response.cm) { - return response.cm; } - throw Error('WS core_course_get_course_module failed.'); + return response.cm; } /** @@ -632,7 +630,7 @@ export class CoreCourseProvider { * @param modicon The mod icon string to use in case we are not using a core activity. * @return The IMG src. */ - getModuleIconSrc(moduleName: string, modicon?: string): string { + async getModuleIconSrc(moduleName: string, modicon?: string): Promise { if (this.CORE_MODULES.indexOf(moduleName) < 0) { if (modicon) { return modicon; diff --git a/src/core/features/course/services/handlers/default-module.ts b/src/core/features/course/services/handlers/default-module.ts index 75dfd0586..d6f7d9637 100644 --- a/src/core/features/course/services/handlers/default-module.ts +++ b/src/core/features/course/services/handlers/default-module.ts @@ -41,12 +41,12 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler { /** * @inheritdoc */ - getData( + async getData( module: CoreCourseAnyModuleData, - ): CoreCourseModuleHandlerData { + ): Promise { // Return the default data. const defaultData: CoreCourseModuleHandlerData = { - icon: CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined), + icon: await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined), title: module.name, class: 'core-course-default-handler core-course-module-' + module.modname + '-handler', action: (event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions) => { diff --git a/src/core/features/course/services/module-delegate.ts b/src/core/features/course/services/module-delegate.ts index 072188859..e7165da57 100644 --- a/src/core/features/course/services/module-delegate.ts +++ b/src/core/features/course/services/module-delegate.ts @@ -56,7 +56,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler { courseId: number, sectionId?: number, forCoursePage?: boolean, - ): CoreCourseModuleHandlerData; + ): Promise | CoreCourseModuleHandlerData; /** * Get the component to render the module. This is needed to support singleactivity course format. @@ -82,7 +82,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler { * * @return The icon src. */ - getIconSrc?(): string | undefined; + getIconSrc?(module: CoreCourseWSModule): Promise | string | undefined; /** * Check if this type of module supports a certain feature. @@ -277,14 +277,14 @@ export class CoreCourseModuleDelegateService extends CoreDelegate( + ): Promise { + return await this.executeFunctionOnEnabled( modname, 'getData', [module, courseId, sectionId, forCoursePage], @@ -343,12 +343,12 @@ export class CoreCourseModuleDelegateService extends CoreDelegate(modname, 'getIconSrc') || - CoreCourse.getModuleIconSrc(modname, modicon) || - ''; + async getModuleIconSrc(modname: string, modicon?: string): Promise { + const icon = await this.executeFunctionOnEnabled>(modname, 'getIconSrc'); + + return icon || await CoreCourse.getModuleIconSrc(modname, modicon) || ''; } /** diff --git a/src/core/features/grades/services/grades-helper.ts b/src/core/features/grades/services/grades-helper.ts index 3d003415b..319dc9313 100644 --- a/src/core/features/grades/services/grades-helper.ts +++ b/src/core/features/grades/services/grades-helper.ts @@ -54,7 +54,7 @@ export class CoreGradesHelperProvider { * @param tableRow JSON object representing row of grades table data. * @return Formatted row object. */ - protected formatGradeRow(tableRow: CoreGradesTableRow): CoreGradesFormattedRow { + protected async formatGradeRow(tableRow: CoreGradesTableRow): Promise { const row: CoreGradesFormattedRow = { rowclass: '', }; @@ -68,7 +68,7 @@ export class CoreGradesHelperProvider { let content = String(column.content); if (name == 'itemname') { - this.setRowIcon(row, content); + await this.setRowIcon(row, content); row.link = this.getModuleLink(content); row.rowclass += column.class.indexOf('hidden') >= 0 ? ' hidden' : ''; row.rowclass += column.class.indexOf('dimmed_text') >= 0 ? ' dimmed_text' : ''; @@ -95,7 +95,7 @@ export class CoreGradesHelperProvider { * @param tableRow JSON object representing row of grades table data. * @return Formatted row object. */ - protected formatGradeRowForTable(tableRow: CoreGradesTableRow): CoreGradesFormattedTableRow { + protected async formatGradeRowForTable(tableRow: CoreGradesTableRow): Promise { const row: CoreGradesFormattedTableRow = {}; for (let name in tableRow) { const column: CoreGradesTableColumn = tableRow[name]; @@ -113,7 +113,7 @@ export class CoreGradesHelperProvider { row.colspan = itemNameColumn.colspan; row.rowspan = tableRow.leader?.rowspan || 1; - this.setRowIcon(row, content); + await this.setRowIcon(row, content); row.rowclass = itemNameColumn.class.indexOf('leveleven') < 0 ? 'odd' : 'even'; row.rowclass += itemNameColumn.class.indexOf('hidden') >= 0 ? ' hidden' : ''; row.rowclass += itemNameColumn.class.indexOf('dimmed_text') >= 0 ? ' dimmed_text' : ''; @@ -158,7 +158,7 @@ export class CoreGradesHelperProvider { * @param table JSON object representing a table with data. * @return Formatted HTML table. */ - formatGradesTable(table: CoreGradesTable): CoreGradesFormattedTable { + async formatGradesTable(table: CoreGradesTable): Promise { const maxDepth = table.maxdepth; const formatted: CoreGradesFormattedTable = { columns: [], @@ -178,7 +178,7 @@ export class CoreGradesHelperProvider { feedback: false, contributiontocoursetotal: false, }; - formatted.rows = table.tabledata.map(row => this.formatGradeRowForTable(row)); + formatted.rows = await Promise.all(table.tabledata.map(row => this.formatGradeRowForTable(row))); // Get a row with some info. let normalRow = formatted.rows.find( @@ -382,7 +382,7 @@ export class CoreGradesHelperProvider { * @param gradeId Grade Object identifier. * @return Formatted HTML table. */ - getGradesTableRow(table: CoreGradesTable, gradeId: number): CoreGradesFormattedRow | null { + async getGradesTableRow(table: CoreGradesTable, gradeId: number): Promise { if (table.tabledata) { const selectedRow = table.tabledata.find( (row) => @@ -393,7 +393,7 @@ export class CoreGradesHelperProvider { ); if (selectedRow) { - return this.formatGradeRow(selectedRow); + return await this.formatGradeRow(selectedRow); } } @@ -408,7 +408,7 @@ export class CoreGradesHelperProvider { * @return Formatted HTML table. * @deprecated since app 4.0 */ - getModuleGradesTableRows(table: CoreGradesTable, moduleId: number): CoreGradesFormattedRow[] { + async getModuleGradesTableRows(table: CoreGradesTable, moduleId: number): Promise { if (!table.tabledata) { return []; } @@ -416,7 +416,7 @@ export class CoreGradesHelperProvider { // Find href containing "/mod/xxx/xxx.php". const regex = /href="([^"]*\/mod\/[^"|^/]*\/[^"|^.]*\.php[^"]*)/; - return table.tabledata.filter((row) => { + return await Promise.all(table.tabledata.filter((row) => { if (row.itemname && row.itemname.content) { const matches = row.itemname.content.match(regex); @@ -428,7 +428,7 @@ export class CoreGradesHelperProvider { } return false; - }).map((row) => this.formatGradeRow(row)); + }).map((row) => this.formatGradeRow(row))); } /** @@ -534,7 +534,7 @@ export class CoreGradesHelperProvider { * @param text HTML where the image will be rendered. * @return Row object with the image. */ - protected setRowIcon(row: T, text: string): T { + protected async setRowIcon(row: T, text: string): Promise { text = text.replace('%2F', '/').replace('%2f', '/'); if (text.indexOf('/agg_mean') > -1) { row.itemtype = 'agg_mean'; @@ -566,7 +566,7 @@ export class CoreGradesHelperProvider { row.itemtype = 'mod'; row.itemmodule = module[1]; row.iconAlt = CoreCourse.translateModuleName(row.itemmodule) || ''; - row.image = CoreCourse.getModuleIconSrc( + row.image = await CoreCourse.getModuleIconSrc( module[1], CoreDomUtils.convertToElement(text).querySelector('img')?.getAttribute('src') ?? undefined, ); diff --git a/src/core/features/sitehome/pages/index/index.ts b/src/core/features/sitehome/pages/index/index.ts index 8976ef25e..7f59dae6d 100644 --- a/src/core/features/sitehome/pages/index/index.ts +++ b/src/core/features/sitehome/pages/index/index.ts @@ -17,7 +17,7 @@ import { IonRefresher } from '@ionic/angular'; import { Params } from '@angular/router'; import { CoreSite, CoreSiteConfig } from '@classes/site'; -import { CoreCourse, CoreCourseModuleBasicInfo, CoreCourseWSSection } from '@features/course/services/course'; +import { CoreCourse, CoreCourseWSModule, CoreCourseWSSection } from '@features/course/services/course'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreSites } from '@services/sites'; import { CoreSiteHome } from '@features/sitehome/services/sitehome'; @@ -48,7 +48,7 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { hasContent = false; items: string[] = []; siteHomeId = 1; - currentSite?: CoreSite; + currentSite!: CoreSite; searchEnabled = false; downloadEnabled = false; downloadCourseEnabled = false; @@ -75,7 +75,7 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { this.switchDownload(this.downloadEnabled && this.downloadCourseEnabled && this.downloadCoursesEnabled); }, CoreSites.getCurrentSiteId()); - this.currentSite = CoreSites.getCurrentSite()!; + this.currentSite = CoreSites.getRequiredCurrentSite(); this.siteHomeId = CoreSites.getCurrentSiteHomeId(); const module = CoreNavigator.getRouteParam('module'); @@ -97,7 +97,7 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { protected async loadContent(): Promise { this.hasContent = false; - const config = this.currentSite!.getStoredConfig() || { numsections: 1, frontpageloggedin: undefined }; + const config = this.currentSite.getStoredConfig() || { numsections: 1, frontpageloggedin: undefined }; this.items = await CoreSiteHome.getFrontPageItems(config.frontpageloggedin); this.hasContent = this.items.length > 0; @@ -105,13 +105,13 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { if (this.items.some((item) => item == 'NEWS_ITEMS')) { // Get the news forum. try { - const forum = await CoreSiteHome.getNewsForum(); - this.newsForumModule = await CoreCourse.getModuleBasicInfo(forum.cmid); - this.newsForumModule.handlerData = CoreCourseModuleDelegate.getModuleDataFor( + const forum = await CoreSiteHome.getNewsForum(this.siteHomeId); + this.newsForumModule = await CoreCourse.getModule(forum.cmid, forum.course); + this.newsForumModule.handlerData = await CoreCourseModuleDelegate.getModuleDataFor( this.newsForumModule.modname, this.newsForumModule, this.siteHomeId, - this.newsForumModule.section, + undefined, true, ); } catch { @@ -120,7 +120,7 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { } try { - const sections = await CoreCourse.getSections(this.siteHomeId!, false, true); + const sections = await CoreCourse.getSections(this.siteHomeId, false, true); // Check "Include a topic section" setting from numsections. this.section = config.numsections ? sections.find((section) => section.section == 1) : undefined; @@ -137,10 +137,10 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { // Add log in Moodle. CoreCourse.logView( - this.siteHomeId!, + this.siteHomeId, undefined, undefined, - this.currentSite!.getInfo()?.sitename, + this.currentSite.getInfo()?.sitename, ).catch(() => { // Ignore errors. }); @@ -157,11 +157,11 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { doRefresh(refresher?: IonRefresher): void { const promises: Promise[] = []; - promises.push(CoreCourse.invalidateSections(this.siteHomeId!)); - promises.push(this.currentSite!.invalidateConfig().then(async () => { + promises.push(CoreCourse.invalidateSections(this.siteHomeId)); + promises.push(this.currentSite.invalidateConfig().then(async () => { // Config invalidated, fetch it again. - const config: CoreSiteConfig = await this.currentSite!.getConfig(); - this.currentSite!.setConfig(config); + const config: CoreSiteConfig = await this.currentSite.getConfig(); + this.currentSite.setConfig(config); return; })); @@ -251,6 +251,6 @@ export class CoreSiteHomeIndexPage implements OnInit, OnDestroy { } -type NewsForum = CoreCourseModuleBasicInfo & { +type NewsForum = CoreCourseWSModule & { handlerData?: CoreCourseModuleHandlerData; }; diff --git a/src/core/features/sitehome/services/sitehome.ts b/src/core/features/sitehome/services/sitehome.ts index 8cb52346d..3de9e2ef9 100644 --- a/src/core/features/sitehome/services/sitehome.ts +++ b/src/core/features/sitehome/services/sitehome.ts @@ -20,6 +20,7 @@ import { makeSingleton } from '@singletons'; import { CoreCourse } from '../../course/services/course'; import { CoreCourses } from '../../courses/services/courses'; import { AddonModForum, AddonModForumData } from '@addons/mod/forum/services/forum'; +import { CoreError } from '@classes/errors/error'; /** * Items with index 1 and 3 were removed on 2.5 and not being supported in the app. @@ -57,7 +58,7 @@ export class CoreSiteHomeProvider { return forum; } - throw null; + throw new CoreError('No news forum found'); } /**