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 1/4] 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');
}
/**
From aa8c6136de59d2ce3a31a3ac922cdee3b18f8308 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Wed, 22 Sep 2021 14:25:02 +0200
Subject: [PATCH 2/4] MOBILE-2748 mod: Use more specific type on module
handlers
---
src/addons/mod/forum/services/handlers/module.ts | 4 ++--
src/addons/mod/label/services/handlers/module.ts | 4 ++--
src/addons/mod/lti/services/handlers/module.ts | 5 ++---
src/addons/mod/resource/services/handlers/module.ts | 12 ++++++------
src/addons/mod/url/services/handlers/module.ts | 12 ++++++------
.../features/course/classes/module-base-handler.ts | 6 +++---
.../course/services/handlers/default-module.ts | 6 +++---
src/core/features/course/services/module-delegate.ts | 4 ++--
8 files changed, 26 insertions(+), 27 deletions(-)
diff --git a/src/addons/mod/forum/services/handlers/module.ts b/src/addons/mod/forum/services/handlers/module.ts
index 7418879ca..98b81258b 100644
--- a/src/addons/mod/forum/services/handlers/module.ts
+++ b/src/addons/mod/forum/services/handlers/module.ts
@@ -14,7 +14,6 @@
import { Injectable, Type } from '@angular/core';
import { AddonModForum, AddonModForumProvider } from '../forum';
-import { CoreCourseAnyModuleData } from '@features/course/services/course';
import { makeSingleton, Translate } from '@singletons';
import { CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites';
@@ -23,6 +22,7 @@ import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/
import { CoreConstants } from '@/core/constants';
import { AddonModForumIndexComponent } from '../../components/index';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
+import { CoreCourseModule } from '@features/course/services/course-helper';
/**
* Handler to support forum modules.
@@ -53,7 +53,7 @@ export class AddonModForumModuleHandlerService extends CoreModuleHandlerBase imp
/**
* @inheritdoc
*/
- async getData(module: CoreCourseAnyModuleData, courseId: number): Promise {
+ async getData(module: CoreCourseModule, courseId: number): Promise {
const data = await super.getData(module, courseId);
if ('afterlink' in module && !!module.afterlink) {
diff --git a/src/addons/mod/label/services/handlers/module.ts b/src/addons/mod/label/services/handlers/module.ts
index c51a15fa0..fe1306f3e 100644
--- a/src/addons/mod/label/services/handlers/module.ts
+++ b/src/addons/mod/label/services/handlers/module.ts
@@ -15,7 +15,7 @@
import { CoreConstants } from '@/core/constants';
import { Injectable } from '@angular/core';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
-import { CoreCourseWSModule } from '@features/course/services/course';
+import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { makeSingleton } from '@singletons';
@@ -44,7 +44,7 @@ export class AddonModLabelModuleHandlerService extends CoreModuleHandlerBase imp
/**
* @inheritdoc
*/
- async getData(module: CoreCourseWSModule): Promise {
+ async getData(module: CoreCourseModule): 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 79d1b90a1..6213d8c9a 100644
--- a/src/addons/mod/lti/services/handlers/module.ts
+++ b/src/addons/mod/lti/services/handlers/module.ts
@@ -16,7 +16,6 @@ import { Injectable, Type } from '@angular/core';
import { CoreConstants } from '@/core/constants';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
-import { CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreApp } from '@services/app';
import { CoreFilepool } from '@services/filepool';
@@ -55,7 +54,7 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple
* @inheritdoc
*/
async getData(
- module: CoreCourseAnyModuleData,
+ module: CoreCourseModule,
courseId: number,
sectionId?: number,
forCoursePage?: boolean,
@@ -87,7 +86,7 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple
* @return Promise resolved when done.
*/
protected async loadCustomIcon(
- module: CoreCourseAnyModuleData,
+ module: CoreCourseModule,
courseId: number,
handlerData: CoreCourseModuleHandlerData,
): Promise {
diff --git a/src/addons/mod/resource/services/handlers/module.ts b/src/addons/mod/resource/services/handlers/module.ts
index f9ed3f2c2..3c6030331 100644
--- a/src/addons/mod/resource/services/handlers/module.ts
+++ b/src/addons/mod/resource/services/handlers/module.ts
@@ -15,7 +15,7 @@
import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
-import { CoreCourse, CoreCourseAnyModuleData, CoreCourseModuleContentFile } from '@features/course/services/course';
+import { CoreCourse, CoreCourseModuleContentFile } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
@@ -64,7 +64,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
* @inheritdoc
*/
async getData(
- module: CoreCourseAnyModuleData,
+ module: CoreCourseModule,
courseId: number,
sectionId?: number,
forCoursePage?: boolean,
@@ -94,7 +94,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
}];
this.getResourceData(module, courseId, handlerData).then((data) => {
- handlerData.icon = data.icon;
+ handlerData.icon = handlerData.icon || data.icon;
handlerData.extraBadge = data.extra;
handlerData.extraBadgeColor = 'light';
@@ -113,7 +113,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
* @param courseId The course ID.
* @return Resolved when done.
*/
- protected async hideOpenButton(module: CoreCourseAnyModuleData, courseId: number): Promise {
+ protected async hideOpenButton(module: CoreCourseModule, courseId: number): Promise {
if (!('contentsinfo' in module) || !module.contentsinfo) {
await CoreCourse.loadModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
}
@@ -131,7 +131,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
* @return Resource data.
*/
protected async getResourceData(
- module: CoreCourseAnyModuleData,
+ module: CoreCourseModule,
courseId: number,
handlerData: CoreCourseModuleHandlerData,
): Promise {
@@ -233,7 +233,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
// No previously set, just set the icon.
if (resourceData.icon == '') {
- resourceData.icon = await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined);
+ resourceData.icon = await CoreCourse.getModuleIconSrc(module.modname, module.modicon);
}
return resourceData;
diff --git a/src/addons/mod/url/services/handlers/module.ts b/src/addons/mod/url/services/handlers/module.ts
index 94634f181..b1cdfaf9e 100644
--- a/src/addons/mod/url/services/handlers/module.ts
+++ b/src/addons/mod/url/services/handlers/module.ts
@@ -16,7 +16,7 @@ import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core';
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
-import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
+import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
@@ -54,7 +54,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
/**
* @inheritdoc
*/
- async getData(module: CoreCourseAnyModuleData, courseId: number): Promise {
+ async getData(module: CoreCourseModule, courseId: number): Promise {
/**
* Open the URL.
@@ -77,7 +77,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
};
const handlerData: CoreCourseModuleHandlerData = {
- icon: await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined),
+ icon: await CoreCourse.getModuleIconSrc(module.modname, module.modicon),
title: module.name,
class: 'addon-mod_url-handler',
showDownloadButton: false,
@@ -120,8 +120,8 @@ 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) ||
- await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined);
+ handlerData.icon = await CoreCourse.getModuleIconSrc(module.modname, module.modicon) ||
+ AddonModUrl.guessIcon(module.contents[0].fileurl);
}
return;
@@ -139,7 +139,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
* @param courseId The course ID.
* @return Resolved when done.
*/
- protected async hideLinkButton(module: CoreCourseAnyModuleData, courseId: number): Promise {
+ protected async hideLinkButton(module: CoreCourseModule, courseId: number): Promise {
try {
const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
diff --git a/src/core/features/course/classes/module-base-handler.ts b/src/core/features/course/classes/module-base-handler.ts
index d44bc8238..f45aa6a53 100644
--- a/src/core/features/course/classes/module-base-handler.ts
+++ b/src/core/features/course/classes/module-base-handler.ts
@@ -13,7 +13,7 @@
// limitations under the License.
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
-import { CoreCourse, CoreCourseAnyModuleData } from '../services/course';
+import { CoreCourse } from '../services/course';
import { CoreCourseModule } from '../services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../services/module-delegate';
@@ -35,13 +35,13 @@ export class CoreModuleHandlerBase implements Partial {
* @inheritdoc
*/
async getData(
- module: CoreCourseAnyModuleData,
+ module: CoreCourseModule,
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
): Promise {
return {
- icon: await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined),
+ icon: await CoreCourse.getModuleIconSrc(module.modname, module.modicon),
title: module.name,
class: 'addon-mod_' + module.modname + '-handler',
showDownloadButton: true,
diff --git a/src/core/features/course/services/handlers/default-module.ts b/src/core/features/course/services/handlers/default-module.ts
index d6f7d9637..25bf41663 100644
--- a/src/core/features/course/services/handlers/default-module.ts
+++ b/src/core/features/course/services/handlers/default-module.ts
@@ -16,7 +16,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreSites } from '@services/sites';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '../module-delegate';
-import { CoreCourse, CoreCourseAnyModuleData } from '../course';
+import { CoreCourse } from '../course';
import { CoreCourseModule } from '../course-helper';
import { CoreCourseUnsupportedModuleComponent } from '@features/course/components/unsupported-module/unsupported-module';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
@@ -42,11 +42,11 @@ export class CoreCourseModuleDefaultHandler implements CoreCourseModuleHandler {
* @inheritdoc
*/
async getData(
- module: CoreCourseAnyModuleData,
+ module: CoreCourseModule,
): Promise {
// Return the default data.
const defaultData: CoreCourseModuleHandlerData = {
- icon: await CoreCourse.getModuleIconSrc(module.modname, 'modicon' in module ? module.modicon : undefined),
+ icon: await CoreCourse.getModuleIconSrc(module.modname, module.modicon),
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 e7165da57..9ff01b011 100644
--- a/src/core/features/course/services/module-delegate.ts
+++ b/src/core/features/course/services/module-delegate.ts
@@ -52,7 +52,7 @@ export interface CoreCourseModuleHandler extends CoreDelegateHandler {
* @return Data to render the module.
*/
getData(
- module: CoreCourseAnyModuleData,
+ module: CoreCourseModule,
courseId: number,
sectionId?: number,
forCoursePage?: boolean,
@@ -279,7 +279,7 @@ export class CoreCourseModuleDelegateService extends CoreDelegate
Date: Mon, 27 Sep 2021 16:44:24 +0200
Subject: [PATCH 3/4] MOBILE-2748 mod: Create a new module icon component
---
.../addon-block-activitymodules.html | 3 +-
.../addon-block-recentlyaccesseditems.html | 4 +-
.../events/addon-block-timeline-events.html | 6 +-
.../timeline/components/events/events.ts | 3 +-
src/addons/calendar/calendar-common.scss | 7 +-
.../calendar/addon-calendar-calendar.html | 5 +-
.../components/calendar/calendar.scss | 8 +-
.../addon-calendar-upcoming-events.html | 4 +-
src/addons/calendar/pages/day/day.html | 5 +-
src/addons/calendar/pages/event/event.html | 3 +-
src/addons/calendar/pages/event/event.scss | 3 +-
.../pages/competency/competency.html | 3 +-
.../coursecompetencies.html | 4 +-
.../mod/lti/services/handlers/module.ts | 50 +----------
.../mod/resource/services/handlers/module.ts | 39 +++-----
.../mod/url/services/handlers/module.ts | 5 +-
.../pages/course-storage/course-storage.html | 5 +-
.../pages/course-storage/course-storage.ts | 2 -
src/core/components/components.module.ts | 3 +
src/core/components/mod-icon/mod-icon.html | 19 ++++
src/core/components/mod-icon/mod-icon.scss | 37 ++++++++
src/core/components/mod-icon/mod-icon.ts | 88 +++++++++++++++++++
.../components/user-avatar/user-avatar.scss | 5 ++
src/core/directives/external-content.ts | 3 +-
.../components/module/core-course-module.html | 5 +-
src/core/features/course/services/course.ts | 19 ++--
.../course/services/module-delegate.ts | 2 +-
.../features/grades/pages/course/course.html | 5 +-
.../grades/pages/course/course.page.ts | 4 +-
.../features/grades/pages/course/course.scss | 10 +++
.../features/grades/pages/grade/grade.html | 9 +-
.../tag/components/feed/core-tag-feed.html | 4 +-
src/theme/theme.base.scss | 26 ------
33 files changed, 251 insertions(+), 147 deletions(-)
create mode 100644 src/core/components/mod-icon/mod-icon.html
create mode 100644 src/core/components/mod-icon/mod-icon.scss
create mode 100644 src/core/components/mod-icon/mod-icon.ts
diff --git a/src/addons/block/activitymodules/components/activitymodules/addon-block-activitymodules.html b/src/addons/block/activitymodules/components/activitymodules/addon-block-activitymodules.html
index 1f39261b4..2306e3b4b 100644
--- a/src/addons/block/activitymodules/components/activitymodules/addon-block-activitymodules.html
+++ b/src/addons/block/activitymodules/components/activitymodules/addon-block-activitymodules.html
@@ -6,7 +6,8 @@
-
+
+
{{ entry.name }}
diff --git a/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/addon-block-recentlyaccesseditems.html b/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/addon-block-recentlyaccesseditems.html
index 4990142ad..73e52969f 100644
--- a/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/addon-block-recentlyaccesseditems.html
+++ b/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/addon-block-recentlyaccesseditems.html
@@ -17,7 +17,9 @@
-
+
+
{{ item.iconTitle }}
diff --git a/src/addons/block/timeline/components/events/addon-block-timeline-events.html b/src/addons/block/timeline/components/events/addon-block-timeline-events.html
index 022dcc211..0622e2e0b 100644
--- a/src/addons/block/timeline/components/events/addon-block-timeline-events.html
+++ b/src/addons/block/timeline/components/events/addon-block-timeline-events.html
@@ -5,10 +5,10 @@
-
+
+
-
- {{ event.iconTitle }}
diff --git a/src/addons/block/timeline/components/events/events.ts b/src/addons/block/timeline/components/events/events.ts
index bf77da586..b0db9c8a0 100644
--- a/src/addons/block/timeline/components/events/events.ts
+++ b/src/addons/block/timeline/components/events/events.ts
@@ -104,7 +104,8 @@ export class AddonBlockTimelineEventsComponent implements OnChanges {
return start <= event.timesort;
}).map(async (event) => {
event.iconUrl = await CoreCourse.getModuleIconSrc(event.icon.component);
- event.iconTitle = event.modulename && CoreCourse.translateModuleName(event.modulename);
+ event.modulename = event.modulename || event.icon.component;
+ event.iconTitle = CoreCourse.translateModuleName(event.modulename);
return event;
}));
diff --git a/src/addons/calendar/calendar-common.scss b/src/addons/calendar/calendar-common.scss
index 771f1987e..8fdaaeefe 100644
--- a/src/addons/calendar/calendar-common.scss
+++ b/src/addons/calendar/calendar-common.scss
@@ -9,6 +9,10 @@
padding: 6px;
}
+ > core-mod-icon {
+ padding: 6px;
+ }
+
&.addon-calendar-eventtype-category > ion-icon {
background-color: var(--addon-calendar-event-category-color);
}
@@ -25,4 +29,5 @@
background-color: var(--addon-calendar-event-site-color);
}
}
-}
+
+}
\ No newline at end of file
diff --git a/src/addons/calendar/components/calendar/addon-calendar-calendar.html b/src/addons/calendar/components/calendar/addon-calendar-calendar.html
index 93d477d00..570926c23 100644
--- a/src/addons/calendar/components/calendar/addon-calendar-calendar.html
+++ b/src/addons/calendar/components/calendar/addon-calendar-calendar.html
@@ -88,8 +88,9 @@
{{ event.timestart * 1000 | coreFormatDate: timeFormat }}
-
+
+
{{ 'addon.calendar.type' + event.formattedType | translate }}
diff --git a/src/addons/calendar/components/calendar/calendar.scss b/src/addons/calendar/components/calendar/calendar.scss
index 4d9303f3b..acbcccf6b 100644
--- a/src/addons/calendar/components/calendar/calendar.scss
+++ b/src/addons/calendar/components/calendar/calendar.scss
@@ -144,15 +144,15 @@
}
}
- .core-module-icon {
+ core-mod-icon {
margin-right: 1px;
margin-left: 1px;
--size: 16px;
display: inline-block;
vertical-align: bottom;
- }
- .core-module-icon[slot="start"] {
- padding: 6px;
+ ::ng-deep img {
+ display: block;
+ }
}
}
diff --git a/src/addons/calendar/components/upcoming-events/addon-calendar-upcoming-events.html b/src/addons/calendar/components/upcoming-events/addon-calendar-upcoming-events.html
index 315e8e624..30c9c2224 100644
--- a/src/addons/calendar/components/upcoming-events/addon-calendar-upcoming-events.html
+++ b/src/addons/calendar/components/upcoming-events/addon-calendar-upcoming-events.html
@@ -6,8 +6,8 @@
-
+
diff --git a/src/addons/calendar/pages/day/day.html b/src/addons/calendar/pages/day/day.html
index 9f4b23431..c0e8bb1d7 100644
--- a/src/addons/calendar/pages/day/day.html
+++ b/src/addons/calendar/pages/day/day.html
@@ -61,8 +61,9 @@
-
+
+
diff --git a/src/addons/calendar/pages/event/event.html b/src/addons/calendar/pages/event/event.html
index 6244bc546..493b41712 100644
--- a/src/addons/calendar/pages/event/event.html
+++ b/src/addons/calendar/pages/event/event.html
@@ -4,7 +4,8 @@
-
+
diff --git a/src/addons/calendar/pages/event/event.scss b/src/addons/calendar/pages/event/event.scss
index bc2bb8cb3..5403de162 100644
--- a/src/addons/calendar/pages/event/event.scss
+++ b/src/addons/calendar/pages/event/event.scss
@@ -2,8 +2,9 @@
ion-card ion-note {
font-size: 1.6rem;
}
- h1 ion-icon, h1 img {
+ h1 ion-icon, h1 img, h1 core-mod-icon {
margin-left: 10px;
margin-right: 10px;
+ display: inline-block;
}
}
diff --git a/src/addons/competency/pages/competency/competency.html b/src/addons/competency/pages/competency/competency.html
index 0406897e2..cc34b86b0 100644
--- a/src/addons/competency/pages/competency/competency.html
+++ b/src/addons/competency/pages/competency/competency.html
@@ -77,8 +77,7 @@
-
+
diff --git a/src/addons/competency/pages/coursecompetencies/coursecompetencies.html b/src/addons/competency/pages/coursecompetencies/coursecompetencies.html
index de2b0bb59..a0e2f63e3 100644
--- a/src/addons/competency/pages/coursecompetencies/coursecompetencies.html
+++ b/src/addons/competency/pages/coursecompetencies/coursecompetencies.html
@@ -114,8 +114,8 @@
-
+
+
diff --git a/src/addons/mod/lti/services/handlers/module.ts b/src/addons/mod/lti/services/handlers/module.ts
index 6213d8c9a..1692ec173 100644
--- a/src/addons/mod/lti/services/handlers/module.ts
+++ b/src/addons/mod/lti/services/handlers/module.ts
@@ -17,13 +17,8 @@ import { Injectable, Type } from '@angular/core';
import { CoreConstants } from '@/core/constants';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreCourseModule } from '@features/course/services/course-helper';
-import { CoreApp } from '@services/app';
-import { CoreFilepool } from '@services/filepool';
-import { CoreSites } from '@services/sites';
-import { CoreUtils } from '@services/utils/utils';
-import { DomSanitizer, makeSingleton } from '@singletons';
+import { makeSingleton } from '@singletons';
import { AddonModLtiHelper } from '../lti-helper';
-import { AddonModLti, AddonModLtiProvider } from '../lti';
import { AddonModLtiIndexComponent } from '../../components/index';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
@@ -62,6 +57,9 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple
const data = await super.getData(module, courseId, sectionId, forCoursePage);
data.showDownloadButton = false;
+ // Handle custom icons.
+ data.icon = module.modicon;
+
data.buttons = [{
icon: 'fas-external-link-alt',
label: 'addon.mod_lti.launchactivity',
@@ -71,49 +69,9 @@ export class AddonModLtiModuleHandlerService extends CoreModuleHandlerBase imple
},
}];
- // Handle custom icons.
- CoreUtils.ignoreErrors(this.loadCustomIcon(module, courseId, data));
-
return data;
}
- /**
- * Load the custom icon.
- *
- * @param module Module.
- * @param courseId Course ID.
- * @param data Handler data.
- * @return Promise resolved when done.
- */
- protected async loadCustomIcon(
- module: CoreCourseModule,
- courseId: number,
- handlerData: CoreCourseModuleHandlerData,
- ): Promise {
- const lti = await AddonModLti.getLti(courseId, module.id);
-
- const icon = lti.secureicon || lti.icon;
- if (!icon) {
- return;
- }
-
- const siteId = CoreSites.getCurrentSiteId();
-
- try {
- await CoreFilepool.downloadUrl(siteId, icon, false, AddonModLtiProvider.COMPONENT, module.id);
-
- // Get the internal URL.
- const url = await CoreFilepool.getSrcByUrl(siteId, icon, AddonModLtiProvider.COMPONENT, module.id);
-
- handlerData.icon = DomSanitizer.bypassSecurityTrustUrl(url);
- } catch {
- // Error downloading. If we're online we'll set the online url.
- if (CoreApp.isOnline()) {
- handlerData.icon = DomSanitizer.bypassSecurityTrustUrl(icon);
- }
- }
- }
-
/**
* @inheritdoc
*/
diff --git a/src/addons/mod/resource/services/handlers/module.ts b/src/addons/mod/resource/services/handlers/module.ts
index 3c6030331..69a3d2ce8 100644
--- a/src/addons/mod/resource/services/handlers/module.ts
+++ b/src/addons/mod/resource/services/handlers/module.ts
@@ -15,7 +15,7 @@
import { CoreConstants } from '@/core/constants';
import { Injectable, Type } from '@angular/core';
import { CoreModuleHandlerBase } from '@features/course/classes/module-base-handler';
-import { CoreCourse, CoreCourseModuleContentFile } from '@features/course/services/course';
+import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModule } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
@@ -23,7 +23,6 @@ import { CoreFileHelper } from '@services/file-helper';
import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time';
-import { CoreWSFile } from '@services/ws';
import { makeSingleton, Translate } from '@singletons';
import { AddonModResourceIndexComponent } from '../../components/index';
import { AddonModResource, AddonModResourceCustomData } from '../resource';
@@ -94,7 +93,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
}];
this.getResourceData(module, courseId, handlerData).then((data) => {
- handlerData.icon = handlerData.icon || data.icon;
+ handlerData.icon = data.icon;
handlerData.extraBadge = data.extra;
handlerData.extraBadgeColor = 'light';
@@ -136,7 +135,6 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
handlerData: CoreCourseModuleHandlerData,
): Promise {
const promises: Promise[] = [];
- let infoFiles: CoreWSFile[] = [];
let options: AddonModResourceCustomData = {};
// Check if the button needs to be shown or not.
@@ -150,12 +148,11 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
return;
}));
- if ('customdata' in module && typeof module.customdata != 'undefined') {
+ if ('customdata' in module && module.customdata !== undefined) {
options = CoreTextUtils.unserialize(CoreTextUtils.parseJSON(module.customdata));
} else {
// Get the resource data.
promises.push(AddonModResource.getResourceData(courseId, module.id).then((info) => {
- infoFiles = info.contentfiles;
options = CoreTextUtils.unserialize(info.displayoptions);
return;
@@ -164,28 +161,22 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
await Promise.all(promises);
- const files: (CoreCourseModuleContentFile | CoreWSFile)[] = module.contents && module.contents.length
- ? module.contents
- : infoFiles;
-
- const resourceData: AddonResourceHandlerData = {
- icon: '',
- extra: '',
- };
+ let mimetypeIcon = '';
const extra: string[] = [];
if ('contentsinfo' in module && module.contentsinfo) {
// No need to use the list of files.
const mimetype = module.contentsinfo.mimetypes[0];
if (mimetype) {
- resourceData.icon = CoreMimetypeUtils.getMimetypeIcon(mimetype);
+ mimetypeIcon = CoreMimetypeUtils.getMimetypeIcon(mimetype);
}
- resourceData.extra = CoreTextUtils.cleanTags(module.afterlink);
+ extra.push(CoreTextUtils.cleanTags(module.afterlink));
- } else if (files && files.length) {
+ } else if (module.contents && module.contents[0]) {
+ const files = module.contents;
const file = files[0];
- resourceData.icon = CoreMimetypeUtils.getFileIcon(file.filename || '');
+ mimetypeIcon = CoreMimetypeUtils.getFileIcon(file.filename || '');
if (options.showsize) {
const size = options.filedetails
@@ -227,16 +218,12 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
));
}
}
-
- resourceData.extra += extra.join(' ');
}
- // No previously set, just set the icon.
- if (resourceData.icon == '') {
- resourceData.icon = await CoreCourse.getModuleIconSrc(module.modname, module.modicon);
- }
-
- return resourceData;
+ return {
+ icon: await CoreCourse.getModuleIconSrc(module.modname, module.modicon, mimetypeIcon),
+ extra: extra.join(' '),
+ };
}
/**
diff --git a/src/addons/mod/url/services/handlers/module.ts b/src/addons/mod/url/services/handlers/module.ts
index b1cdfaf9e..e6257f845 100644
--- a/src/addons/mod/url/services/handlers/module.ts
+++ b/src/addons/mod/url/services/handlers/module.ts
@@ -119,9 +119,10 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
handlerData.buttons[0].hidden = hideButton;
if (module.contents && module.contents[0]) {
+ const icon = AddonModUrl.guessIcon(module.contents[0].fileurl);
+
// Calculate the icon to use.
- handlerData.icon = await CoreCourse.getModuleIconSrc(module.modname, module.modicon) ||
- AddonModUrl.guessIcon(module.contents[0].fileurl);
+ handlerData.icon = await CoreCourse.getModuleIconSrc(module.modname, module.modicon, icon);
}
return;
diff --git a/src/addons/storagemanager/pages/course-storage/course-storage.html b/src/addons/storagemanager/pages/course-storage/course-storage.html
index 1220ca816..a2417b7ac 100644
--- a/src/addons/storagemanager/pages/course-storage/course-storage.html
+++ b/src/addons/storagemanager/pages/course-storage/course-storage.html
@@ -45,8 +45,9 @@
0">
-
+
+
{{ module.name }}
diff --git a/src/addons/storagemanager/pages/course-storage/course-storage.ts b/src/addons/storagemanager/pages/course-storage/course-storage.ts
index 752059a7a..e52ddb0e0 100644
--- a/src/addons/storagemanager/pages/course-storage/course-storage.ts
+++ b/src/addons/storagemanager/pages/course-storage/course-storage.ts
@@ -63,7 +63,6 @@ export class AddonStorageManagerCourseStoragePage implements OnInit {
section.modules.forEach((module) => {
module.parentSection = section;
module.totalSize = 0;
- module.modNameTranslated = CoreCourse.translateModuleName(module.modname) || '';
// Note: This function only gets the size for modules which are downloadable.
// For other modules it always returns 0, even if they have downloaded some files.
@@ -235,5 +234,4 @@ type AddonStorageManagerCourseSection = Omit & {
type AddonStorageManagerModule = CoreCourseModule & {
parentSection?: AddonStorageManagerCourseSection;
totalSize?: number;
- modNameTranslated?: string;
};
diff --git a/src/core/components/components.module.ts b/src/core/components/components.module.ts
index ee3d02b2e..b055bad15 100644
--- a/src/core/components/components.module.ts
+++ b/src/core/components/components.module.ts
@@ -40,6 +40,7 @@ import { CoreInputErrorsComponent } from './input-errors/input-errors';
import { CoreLoadingComponent } from './loading/loading';
import { CoreLocalFileComponent } from './local-file/local-file';
import { CoreMarkRequiredComponent } from './mark-required/mark-required';
+import { CoreModIconComponent } from './mod-icon/mod-icon';
import { CoreNavBarButtonsComponent } from './navbar-buttons/navbar-buttons';
import { CoreNavigationBarComponent } from './navigation-bar/navigation-bar';
import { CoreProgressBarComponent } from './progress-bar/progress-bar';
@@ -81,6 +82,7 @@ import { CoreButtonWithSpinnerComponent } from './button-with-spinner/button-wit
CoreLoadingComponent,
CoreLocalFileComponent,
CoreMarkRequiredComponent,
+ CoreModIconComponent,
CoreNavBarButtonsComponent,
CoreNavigationBarComponent,
CoreProgressBarComponent,
@@ -128,6 +130,7 @@ import { CoreButtonWithSpinnerComponent } from './button-with-spinner/button-wit
CoreLoadingComponent,
CoreLocalFileComponent,
CoreMarkRequiredComponent,
+ CoreModIconComponent,
CoreNavBarButtonsComponent,
CoreNavigationBarComponent,
CoreProgressBarComponent,
diff --git a/src/core/components/mod-icon/mod-icon.html b/src/core/components/mod-icon/mod-icon.html
new file mode 100644
index 000000000..4ce9eef5c
--- /dev/null
+++ b/src/core/components/mod-icon/mod-icon.html
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/src/core/components/mod-icon/mod-icon.scss b/src/core/components/mod-icon/mod-icon.scss
new file mode 100644
index 000000000..e8cbb5754
--- /dev/null
+++ b/src/core/components/mod-icon/mod-icon.scss
@@ -0,0 +1,37 @@
+:host {
+ --size: var(--module-icon-size);
+ --margin-end: 0px;
+ --margin-vertical: 0px;
+
+ margin-top: var(--margin-vertical);
+ margin-bottom: var(--margin-vertical);
+ margin-right: var(--margin-end);
+}
+
+img {
+ width: var(--size);
+ height: var(--size);
+ max-width: var(--size);
+ max-height: var(--size);
+
+ &[alt] {
+ text-indent: -999999px;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+}
+
+:host-context(ion-item) {
+ --margin-vertical: 12px;
+ --margin-end: 32px;
+}
+
+:host-context(ion-card ion-item) {
+ --margin-vertical: 12px;
+ --margin-end: 12px;
+}
+
+:host-context([dir=rtl]) {
+ margin-right: unset;
+ margin-left: var(--margin-end);
+}
\ No newline at end of file
diff --git a/src/core/components/mod-icon/mod-icon.ts b/src/core/components/mod-icon/mod-icon.ts
new file mode 100644
index 000000000..eba805215
--- /dev/null
+++ b/src/core/components/mod-icon/mod-icon.ts
@@ -0,0 +1,88 @@
+// (C) Copyright 2015 Moodle Pty Ltd.
+//
+// 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 { Component, Input, OnChanges, OnInit, SimpleChange } from '@angular/core';
+import { CoreCourse } from '@features/course/services/course';
+
+const assetsPath = 'assets/img/mod/';
+const fallbackModName = 'external-tool';
+
+/**
+ * Component to handle a module icon.
+ */
+@Component({
+ selector: 'core-mod-icon',
+ templateUrl: 'mod-icon.html',
+ styleUrls: ['mod-icon.scss'],
+})
+export class CoreModIconComponent implements OnInit, OnChanges {
+
+ @Input() modname?; // The module name. Used also as component if set.
+ @Input() componentId?; // Component Id for external icons.
+ @Input() modicon?: string; // Module icon url or local url.
+ @Input() showAlt = true; // Show alt otherwise it's only presentation icon.
+
+ icon = '';
+ modNameTranslated = '';
+ isLocalUrl = true;
+ linkIconWithComponent = false;
+
+ /**
+ * @inheritdoc
+ */
+ async ngOnInit(): Promise {
+ this.modNameTranslated = this.modname ? CoreCourse.translateModuleName(this.modname) || '' : '';
+
+ this.setIcon();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ ngOnChanges(changes: { [name: string]: SimpleChange }): void {
+ if (changes && changes.modicon && changes.modicon.previousValue) {
+ this.setIcon();
+ }
+ }
+
+ /**
+ * Set icon.
+ */
+ setIcon(): void {
+ this.icon = this.modicon || this.icon;
+ this.isLocalUrl = this.icon.startsWith(assetsPath);
+
+ // Cache icon if the url is not the theme generic one.
+ // If modname is not set icon won't be cached.
+ // Also if the url matches the regexp (the theme will manage the image so it's not cached).
+ this.linkIconWithComponent =
+ this.modname &&
+ this.componentId &&
+ !this.isLocalUrl &&
+ !this.icon.match('/theme/image.php/[^/]+/' + this.modname + '/[-0-9]*/');
+ }
+
+ /**
+ * Icon to load on error.
+ */
+ loadFallbackIcon(): void {
+ this.isLocalUrl = true;
+ const moduleName = !this.modname || CoreCourse.CORE_MODULES.indexOf(this.modname) < 0
+ ? fallbackModName
+ : this.modname;
+
+ this.icon = assetsPath + moduleName + '.svg';
+ }
+
+}
diff --git a/src/core/components/user-avatar/user-avatar.scss b/src/core/components/user-avatar/user-avatar.scss
index 6ae01b259..5d99ba41d 100644
--- a/src/core/components/user-avatar/user-avatar.scss
+++ b/src/core/components/user-avatar/user-avatar.scss
@@ -79,3 +79,8 @@
left: 0;
right: unset;
}
+
+:host-context(ion-item) {
+ margin-top: 12px;
+ margin-bottom: 12px;
+}
\ No newline at end of file
diff --git a/src/core/directives/external-content.ts b/src/core/directives/external-content.ts
index 4dd8f719f..4d84f6845 100644
--- a/src/core/directives/external-content.ts
+++ b/src/core/directives/external-content.ts
@@ -113,8 +113,7 @@ export class CoreExternalContentDirective implements AfterViewInit, OnChanges {
* Get the URL that should be handled and, if valid, handle it.
*/
protected async checkAndHandleExternalContent(): Promise {
- const currentSite = CoreSites.getCurrentSite();
- const siteId = this.siteId || currentSite?.getId();
+ const siteId = this.siteId || CoreSites.getRequiredCurrentSite().getId();
const tagName = this.element.tagName.toUpperCase();
let targetAttr;
let url;
diff --git a/src/core/features/course/components/module/core-course-module.html b/src/core/features/course/components/module/core-course-module.html
index bbfebb68c..630c19e11 100644
--- a/src/core/features/course/components/module/core-course-module.html
+++ b/src/core/features/course/components/module/core-course-module.html
@@ -13,8 +13,9 @@
[button]="module.handlerData.action && module.uservisible"
detail="false">
-
+
+
diff --git a/src/core/features/course/services/course.ts b/src/core/features/course/services/course.ts
index 0e7f38649..81505df14 100644
--- a/src/core/features/course/services/course.ts
+++ b/src/core/features/course/services/course.ts
@@ -83,7 +83,7 @@ export class CoreCourseProvider {
static readonly COMPONENT = 'CoreCourse';
- protected readonly CORE_MODULES = [
+ readonly CORE_MODULES = [
'assign', 'assignment', 'book', 'chat', 'choice', 'data', 'database', 'date', 'external-tool',
'feedback', 'file', 'folder', 'forum', 'glossary', 'ims', 'imscp', 'label', 'lesson', 'lti', 'page', 'quiz',
'resource', 'scorm', 'survey', 'url', 'wiki', 'workshop', 'h5pactivity',
@@ -402,15 +402,16 @@ export class CoreCourseProvider {
): Promise => {
const params: CoreCourseGetContentsParams = {
courseid: courseId!,
- options: [],
};
+ params.options = [];
+
const preSets: CoreSiteWSPreSets = {
omitExpires: preferCache,
updateFrequency: CoreSite.FREQUENCY_RARELY,
};
if (includeStealth) {
- params.options!.push({
+ params.options.push({
name: 'includestealthmodules',
value: true,
});
@@ -418,13 +419,13 @@ export class CoreCourseProvider {
// If modName is set, retrieve all modules of that type. Otherwise get only the module.
if (modName) {
- params.options!.push({
+ params.options.push({
name: 'modname',
value: modName,
});
preSets.cacheKey = this.getModuleByModNameCacheKey(modName);
} else {
- params.options!.push({
+ params.options.push({
name: 'cmid',
value: moduleId,
});
@@ -630,7 +631,11 @@ export class CoreCourseProvider {
* @param modicon The mod icon string to use in case we are not using a core activity.
* @return The IMG src.
*/
- async getModuleIconSrc(moduleName: string, modicon?: string): Promise {
+ async getModuleIconSrc(moduleName: string, modicon?: string, mimetypeIcon = ''): Promise {
+ if (mimetypeIcon) {
+ return mimetypeIcon;
+ }
+
if (this.CORE_MODULES.indexOf(moduleName) < 0) {
if (modicon) {
return modicon;
@@ -1489,7 +1494,7 @@ export type CoreCourseWSModule = {
label: string;
timestamp: number;
}[]; // @since 3.11. Activity dates.
- contentsinfo?: { // Contents summary information.
+ contentsinfo?: { // @since v3.7.6 Contents summary information.
filescount: number; // Total number of files.
filessize: number; // Total files size.
lastmodified: number; // Last time files were modified.
diff --git a/src/core/features/course/services/module-delegate.ts b/src/core/features/course/services/module-delegate.ts
index 9ff01b011..f967c89a5 100644
--- a/src/core/features/course/services/module-delegate.ts
+++ b/src/core/features/course/services/module-delegate.ts
@@ -20,7 +20,7 @@ import { CoreSite } from '@classes/site';
import { CoreCourseModuleDefaultHandler } from './handlers/default-module';
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
-import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from './course';
+import { CoreCourse, CoreCourseWSModule } from './course';
import { CoreSites } from '@services/sites';
import { makeSingleton } from '@singletons';
import { CoreCourseModule } from './course-helper';
diff --git a/src/core/features/grades/pages/course/course.html b/src/core/features/grades/pages/course/course.html
index c4d8ee0fd..3883ca2d3 100644
--- a/src/core/features/grades/pages/course/course.html
+++ b/src/core/features/grades/pages/course/course.html
@@ -52,8 +52,11 @@
>
-
+
+
diff --git a/src/core/features/grades/pages/course/course.page.ts b/src/core/features/grades/pages/course/course.page.ts
index ee13e8248..224d9369b 100644
--- a/src/core/features/grades/pages/course/course.page.ts
+++ b/src/core/features/grades/pages/course/course.page.ts
@@ -114,7 +114,7 @@ export class CoreGradesCoursePage implements AfterViewInit, OnDestroy {
* Update the table of grades.
*/
private async fetchGrades(): Promise {
- const table = await CoreGrades.getCourseGradesTable(this.grades.courseId!, this.grades.userId);
+ const table = await CoreGrades.getCourseGradesTable(this.grades.courseId, this.grades.userId);
const formattedTable = await CoreGradesHelper.formatGradesTable(table);
this.grades.setTable(formattedTable);
@@ -192,7 +192,7 @@ class CoreGradesCourseManager extends CorePageItemsListManager {
- await CoreGrades.logCourseGradesView(this.courseId!, this.userId!);
+ await CoreGrades.logCourseGradesView(this.courseId, this.userId);
}
/**
diff --git a/src/core/features/grades/pages/course/course.scss b/src/core/features/grades/pages/course/course.scss
index aca518a0f..2f0239c09 100644
--- a/src/core/features/grades/pages/course/course.scss
+++ b/src/core/features/grades/pages/course/course.scss
@@ -82,6 +82,11 @@
height: 16px;
}
+ core-mod-icon {
+ --size: 16px;
+ }
+
+
ion-icon {
color: var(--icon-color);
}
@@ -119,6 +124,11 @@
background-color: var(--cell-hover);
}
}
+
+ th, td {
+ height: var(--a11y-min-target-size);
+ vertical-align: middle;
+ }
}
}
diff --git a/src/core/features/grades/pages/grade/grade.html b/src/core/features/grades/pages/grade/grade.html
index 4b3198ee2..9abe2b1f3 100644
--- a/src/core/features/grades/pages/grade/grade.html
+++ b/src/core/features/grades/pages/grade/grade.html
@@ -17,8 +17,9 @@
-
+
+
+
@@ -27,7 +28,9 @@
-
+
+
+
diff --git a/src/core/features/tag/components/feed/core-tag-feed.html b/src/core/features/tag/components/feed/core-tag-feed.html
index b0f626f67..1be13ee74 100644
--- a/src/core/features/tag/components/feed/core-tag-feed.html
+++ b/src/core/features/tag/components/feed/core-tag-feed.html
@@ -3,8 +3,8 @@
-
+
+
{{ item.heading }}
{{ text }}
diff --git a/src/theme/theme.base.scss b/src/theme/theme.base.scss
index ef149d2ca..0253a989c 100644
--- a/src/theme/theme.base.scss
+++ b/src/theme/theme.base.scss
@@ -527,36 +527,10 @@ img[core-external-content]:not([src]) {
visibility: hidden;
}
-// Activity modules
-.core-module-icon {
- --size: var(--module-icon-size);
- width: var(--size);
- height: var(--size);
- max-width: var(--size);
- max-height: var(--size);
-}
-
-ion-item img.core-module-icon[slot="start"] {
- margin-top: 12px;
- margin-bottom: 12px;
- margin-right: 32px;
-}
-
-ion-card ion-item img.core-module-icon[slot="start"] {
- margin-top: 12px;
- margin-bottom: 12px;
- margin-right: 12px;
-}
-
ion-card ion-item:only-child {
--inner-border-width: 0;
}
-[dir=rtl] ion-item img.core-module-icon[slot="start"] {
- margin-right: unset;
- margin-left: 32px;
-}
-
.core-course-module-handler:not(.addon-mod-label-handler) .item-heading .filter_mathjaxloader_equation div {
display: inline !important;
}
From eb34039be905990a008defe208a1eff0e8189e21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?=
Date: Tue, 28 Sep 2021 12:17:17 +0200
Subject: [PATCH 4/4] MOBILE-2748 github: Ignore warnings during linter on
testing
---
.github/workflows/testing.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index 5b10f13a3..6e5aed17e 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -51,8 +51,8 @@ jobs:
echo "Found $found missing langkeys"
exit 1
fi
- - name: Run Linter
- run: npm run lint
+ - name: Run Linter (ignore warnings)
+ run: npm run lint -- --quiet
- name: Run tests
run: npm run test:ci
- name: Production builds