commit
44b9f499bf
|
@ -17,7 +17,7 @@ import { CoreSites } from '@services/sites';
|
|||
import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
|
||||
import {
|
||||
AddonBlockRecentlyAccessedItems,
|
||||
AddonBlockRecentlyAccessedItemsItem,
|
||||
AddonBlockRecentlyAccessedItemsItemCalculatedData,
|
||||
} from '../../services/recentlyaccesseditems';
|
||||
import { CoreTextUtils } from '@services/utils/text';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
|
@ -33,7 +33,7 @@ import { CoreUtils } from '@services/utils/utils';
|
|||
})
|
||||
export class AddonBlockRecentlyAccessedItemsComponent extends CoreBlockBaseComponent implements OnInit {
|
||||
|
||||
items: AddonBlockRecentlyAccessedItemsItem[] = [];
|
||||
items: AddonBlockRecentlyAccessedItemsItemCalculatedData[] = [];
|
||||
scrollElementId!: string;
|
||||
|
||||
protected fetchContentDefaultError = 'Error getting recently accessed items data.';
|
||||
|
@ -79,7 +79,7 @@ export class AddonBlockRecentlyAccessedItemsComponent extends CoreBlockBaseCompo
|
|||
* @param item Activity item info.
|
||||
* @returns Promise resolved when done.
|
||||
*/
|
||||
async action(e: Event, item: AddonBlockRecentlyAccessedItemsItem): Promise<void> {
|
||||
async action(e: Event, item: AddonBlockRecentlyAccessedItemsItemCalculatedData): Promise<void> {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
|
|
|
@ -38,24 +38,35 @@ export class AddonBlockRecentlyAccessedItemsProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get last accessed items.
|
||||
* Get last accessed items from WS.
|
||||
*
|
||||
* @param siteId Site ID. If not defined, use current site.
|
||||
* @returns Promise resolved when the info is retrieved.
|
||||
*/
|
||||
async getRecentItems(siteId?: string): Promise<AddonBlockRecentlyAccessedItemsItem[]> {
|
||||
protected async getRecentItemsWS(siteId?: string): Promise<AddonBlockRecentlyaccesseditemsGetRecentItemsWSResponse[]> {
|
||||
const site = await CoreSites.getSite(siteId);
|
||||
|
||||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getRecentItemsCacheKey(),
|
||||
};
|
||||
|
||||
let items: AddonBlockRecentlyAccessedItemsItem[] =
|
||||
await site.read('block_recentlyaccesseditems_get_recent_items', undefined, preSets);
|
||||
return await site.read('block_recentlyaccesseditems_get_recent_items', undefined, preSets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last accessed items.
|
||||
*
|
||||
* @param siteId Site ID. If not defined, use current site.
|
||||
* @returns Promise resolved when the info is retrieved with some calculated data.
|
||||
*/
|
||||
async getRecentItems(siteId?: string): Promise<AddonBlockRecentlyAccessedItemsItemCalculatedData[]> {
|
||||
const site = await CoreSites.getSite(siteId);
|
||||
|
||||
const items = await this.getRecentItemsWS(site.getId());
|
||||
|
||||
const cmIds: number[] = [];
|
||||
|
||||
items = await Promise.all(items.map(async (item) => {
|
||||
const itemsToDisplay = await Promise.all(items.map(async (item: AddonBlockRecentlyAccessedItemsItemCalculatedData) => {
|
||||
const modicon = item.icon && CoreDomUtils.getHTMLElementAttribute(item.icon, 'src');
|
||||
|
||||
item.iconUrl = await CoreCourseModuleDelegate.getModuleIconSrc(item.modname, modicon || undefined);
|
||||
|
@ -68,7 +79,7 @@ export class AddonBlockRecentlyAccessedItemsProvider {
|
|||
// Check if the viewed module should be updated for each activity.
|
||||
const lastViewedMap = await CoreCourse.getCertainModulesViewed(cmIds, site.getId());
|
||||
|
||||
items.forEach((recentItem) => {
|
||||
itemsToDisplay.forEach((recentItem) => {
|
||||
const timeAccess = recentItem.timeaccess * 1000;
|
||||
const lastViewed = lastViewedMap[recentItem.cmid];
|
||||
|
||||
|
@ -84,7 +95,7 @@ export class AddonBlockRecentlyAccessedItemsProvider {
|
|||
});
|
||||
});
|
||||
|
||||
return items;
|
||||
return itemsToDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,11 +114,11 @@ export class AddonBlockRecentlyAccessedItemsProvider {
|
|||
export const AddonBlockRecentlyAccessedItems = makeSingleton(AddonBlockRecentlyAccessedItemsProvider);
|
||||
|
||||
/**
|
||||
* Result of WS block_recentlyaccesseditems_get_recent_items.
|
||||
* Data returned by block_recentlyaccesseditems_get_recent_items WS.
|
||||
*
|
||||
* The most recently accessed activities/resources by the logged user.
|
||||
*/
|
||||
export type AddonBlockRecentlyAccessedItemsItem = {
|
||||
type AddonBlockRecentlyaccesseditemsGetRecentItemsWSResponse = {
|
||||
id: number; // Id.
|
||||
courseid: number; // Courseid.
|
||||
cmid: number; // Cmid.
|
||||
|
@ -120,12 +131,13 @@ export type AddonBlockRecentlyAccessedItemsItem = {
|
|||
courseviewurl: string; // Courseviewurl.
|
||||
icon: string; // Icon.
|
||||
purpose?: string; // Purpose. @since 4.0
|
||||
} & AddonBlockRecentlyAccessedItemsItemCalculatedData;
|
||||
branded?: boolean; // Branded. @since 4.4
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculated data for recently accessed item.
|
||||
*/
|
||||
export type AddonBlockRecentlyAccessedItemsItemCalculatedData = {
|
||||
export type AddonBlockRecentlyAccessedItemsItemCalculatedData = AddonBlockRecentlyaccesseditemsGetRecentItemsWSResponse & {
|
||||
iconUrl: string; // Icon URL. Calculated by the app.
|
||||
iconTitle?: string | null; // Icon title.
|
||||
};
|
||||
|
|
|
@ -15,26 +15,21 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import {
|
||||
AddonCalendarEvents,
|
||||
AddonCalendarEventsGroupedByCourse,
|
||||
AddonCalendarEvent,
|
||||
AddonCalendarGetActionEventsByCourseWSParams,
|
||||
AddonCalendarGetActionEventsByTimesortWSParams,
|
||||
AddonCalendarGetActionEventsByCoursesWSParams,
|
||||
} from '@addons/calendar/services/calendar';
|
||||
import moment from 'moment-timezone';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
|
||||
|
||||
// Cache key was maintained from block myoverview when blocks were splitted.
|
||||
const ROOT_CACHE_KEY = 'myoverview:';
|
||||
|
||||
/**
|
||||
* Service that provides some features regarding course overview.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonBlockTimelineProvider {
|
||||
|
||||
// Cache key was maintained from block myoverview when blocks were splitted.
|
||||
protected static readonly ROOT_CACHE_KEY = 'myoverview:';
|
||||
|
||||
static readonly EVENTS_LIMIT = 20;
|
||||
static readonly EVENTS_LIMIT_PER_COURSE = 10;
|
||||
|
||||
|
@ -57,7 +52,7 @@ export class AddonBlockTimelineProvider {
|
|||
|
||||
const time = this.getDayStart(-14); // Check two weeks ago.
|
||||
|
||||
const data: AddonCalendarGetActionEventsByCourseWSParams = {
|
||||
const data: AddonBlockTimelineGetActionEventsByCourseWSParams = {
|
||||
timesortfrom: time,
|
||||
courseid: courseId,
|
||||
limitnum: AddonBlockTimelineProvider.EVENTS_LIMIT_PER_COURSE,
|
||||
|
@ -75,7 +70,7 @@ export class AddonBlockTimelineProvider {
|
|||
preSets.getFromCache = false;
|
||||
}
|
||||
|
||||
const courseEvents = await site.read<AddonCalendarEvents>(
|
||||
const courseEvents = await site.read<AddonBlockTimelineGetActionEventsByCourseWSResponse>(
|
||||
'core_calendar_get_action_events_by_course',
|
||||
data,
|
||||
preSets,
|
||||
|
@ -115,7 +110,7 @@ export class AddonBlockTimelineProvider {
|
|||
|
||||
const time = this.getDayStart(-14); // Check two weeks ago.
|
||||
|
||||
const data: AddonCalendarGetActionEventsByCoursesWSParams = {
|
||||
const data: AddonBlockTimelineGetActionEventsByCoursesWSParams = {
|
||||
timesortfrom: time,
|
||||
courseids: courseIds,
|
||||
limitnum: AddonBlockTimelineProvider.EVENTS_LIMIT_PER_COURSE,
|
||||
|
@ -129,7 +124,7 @@ export class AddonBlockTimelineProvider {
|
|||
preSets.getFromCache = false;
|
||||
}
|
||||
|
||||
const events = await site.read<AddonCalendarEventsGroupedByCourse>(
|
||||
const events = await site.read<AddonBlockTimelineGetActionEventsByCoursesWSResponse>(
|
||||
'core_calendar_get_action_events_by_courses',
|
||||
data,
|
||||
preSets,
|
||||
|
@ -150,7 +145,7 @@ export class AddonBlockTimelineProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getActionEventsByCoursesCacheKey(): string {
|
||||
return ROOT_CACHE_KEY + 'bycourse';
|
||||
return AddonBlockTimelineProvider.ROOT_CACHE_KEY + 'bycourse';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,7 +166,7 @@ export class AddonBlockTimelineProvider {
|
|||
const timesortfrom = this.getDayStart(-14); // Check two weeks ago.
|
||||
const limitnum = AddonBlockTimelineProvider.EVENTS_LIMIT;
|
||||
|
||||
const data: AddonCalendarGetActionEventsByTimesortWSParams = {
|
||||
const data: AddonBlockTimelineGetActionEventsByTimesortWSParams = {
|
||||
timesortfrom,
|
||||
limitnum,
|
||||
limittononsuspendedevents: true,
|
||||
|
@ -192,7 +187,7 @@ export class AddonBlockTimelineProvider {
|
|||
preSets.cacheKey += ':' + searchValue;
|
||||
}
|
||||
|
||||
const result = await site.read<AddonCalendarEvents>(
|
||||
const result = await site.read<AddonBlockTimelineGetActionEventsByTimesortWSResponse>(
|
||||
'core_calendar_get_action_events_by_timesort',
|
||||
data,
|
||||
preSets,
|
||||
|
@ -215,7 +210,7 @@ export class AddonBlockTimelineProvider {
|
|||
* @returns Cache key.
|
||||
*/
|
||||
protected getActionEventsByTimesortPrefixCacheKey(): string {
|
||||
return ROOT_CACHE_KEY + 'bytimesort:';
|
||||
return AddonBlockTimelineProvider.ROOT_CACHE_KEY + 'bytimesort:';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -264,7 +259,7 @@ export class AddonBlockTimelineProvider {
|
|||
* @returns Object with course events and last loaded event id if more can be loaded.
|
||||
*/
|
||||
protected treatCourseEvents(
|
||||
course: AddonCalendarEvents,
|
||||
course: AddonBlockTimelineEvents,
|
||||
timeFrom: number,
|
||||
): { events: AddonCalendarEvent[]; canLoadMore?: number } {
|
||||
|
||||
|
@ -293,3 +288,77 @@ export class AddonBlockTimelineProvider {
|
|||
}
|
||||
|
||||
export const AddonBlockTimeline = makeSingleton(AddonBlockTimelineProvider);
|
||||
|
||||
/**
|
||||
* Params of core_calendar_get_action_events_by_timesort WS.
|
||||
*/
|
||||
type AddonBlockTimelineGetActionEventsByTimesortWSParams = {
|
||||
timesortfrom?: number; // Time sort from.
|
||||
timesortto?: number; // Time sort to.
|
||||
aftereventid?: number; // The last seen event id.
|
||||
limitnum?: number; // Limit number.
|
||||
limittononsuspendedevents?: boolean; // Limit the events to courses the user is not suspended in.
|
||||
userid?: number; // The user id.
|
||||
searchvalue?: string; // The value a user wishes to search against.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by core_calendar_get_action_events_by_timesort WS.
|
||||
*
|
||||
* WS Description: Get calendar action events by tiemsort
|
||||
*/
|
||||
type AddonBlockTimelineGetActionEventsByTimesortWSResponse = AddonBlockTimelineEvents;
|
||||
|
||||
/**
|
||||
* Params of core_calendar_get_action_events_by_course WS.
|
||||
*/
|
||||
type AddonBlockTimelineGetActionEventsByCourseWSParams = {
|
||||
courseid: number; // Course id.
|
||||
timesortfrom?: number; // Time sort from.
|
||||
timesortto?: number; // Time sort to.
|
||||
aftereventid?: number; // The last seen event id.
|
||||
limitnum?: number; // Limit number.
|
||||
searchvalue?: string; // The value a user wishes to search against.
|
||||
};
|
||||
|
||||
/**
|
||||
* Params of core_calendar_get_action_events_by_courses WS.
|
||||
*/
|
||||
type AddonBlockTimelineGetActionEventsByCoursesWSParams = {
|
||||
courseids: number[];
|
||||
timesortfrom?: number; // Time sort from.
|
||||
timesortto?: number; // Time sort to.
|
||||
limitnum?: number; // Limit number.
|
||||
searchvalue?: string; // The value a user wishes to search against.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by calendar's events_grouped_by_course_exporter.
|
||||
* Data returned by core_calendar_get_action_events_by_courses WS.
|
||||
*/
|
||||
type AddonBlockTimelineGetActionEventsByCoursesWSResponse = {
|
||||
groupedbycourse: AddonBlockTimelineEventsSameCourse[]; // Groupped by course.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by calendar's events_same_course_exporter.
|
||||
*/
|
||||
type AddonBlockTimelineEventsSameCourse = AddonBlockTimelineEvents & {
|
||||
courseid: number; // Courseid.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by core_calendar_get_action_events_by_course WS.
|
||||
*
|
||||
* WS Description: Get calendar action events by course
|
||||
*/
|
||||
type AddonBlockTimelineGetActionEventsByCourseWSResponse = AddonBlockTimelineEvents;
|
||||
|
||||
/**
|
||||
* Data returned by calendar's events_exporter.
|
||||
*/
|
||||
export type AddonBlockTimelineEvents = {
|
||||
events: AddonCalendarEvent[]; // Events.
|
||||
firstid: number; // Firstid.
|
||||
lastid: number; // Lastid.
|
||||
};
|
||||
|
|
|
@ -31,8 +31,7 @@
|
|||
<ion-list *ngIf="event">
|
||||
<ion-item class="ion-text-wrap addon-calendar-event" collapsible [ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
|
||||
<core-mod-icon *ngIf="event.moduleIcon" [modicon]="event.moduleIcon" [showAlt]="false" [modname]="event.modulename"
|
||||
[componentId]="event.instance" slot="start" [purpose]="event.purpose" />
|
||||
<!-- TODO MOBILE-4530 Add isBranded when available -->
|
||||
[componentId]="event.instance" slot="start" [purpose]="event.purpose" [isBranded]="event.branded" />
|
||||
<ion-icon *ngIf=" event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" aria-hidden="true" slot="start" />
|
||||
<ion-label>
|
||||
<!-- Add the icon title so accessibility tools read it. -->
|
||||
|
|
|
@ -1744,67 +1744,6 @@ export class AddonCalendarProvider {
|
|||
|
||||
export const AddonCalendar = makeSingleton(AddonCalendarProvider);
|
||||
|
||||
/**
|
||||
* Data returned by calendar's events_exporter.
|
||||
* Data returned by core_calendar_get_action_events_by_course and core_calendar_get_action_events_by_timesort WS.
|
||||
*/
|
||||
export type AddonCalendarEvents = {
|
||||
events: AddonCalendarEvent[]; // Events.
|
||||
firstid: number; // Firstid.
|
||||
lastid: number; // Lastid.
|
||||
};
|
||||
|
||||
/**
|
||||
* Params of core_calendar_get_action_events_by_courses WS.
|
||||
*/
|
||||
export type AddonCalendarGetActionEventsByCoursesWSParams = {
|
||||
courseids: number[];
|
||||
timesortfrom?: number; // Time sort from.
|
||||
timesortto?: number; // Time sort to.
|
||||
limitnum?: number; // Limit number.
|
||||
searchvalue?: string; // The value a user wishes to search against.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by calendar's events_grouped_by_course_exporter.
|
||||
* Data returned by core_calendar_get_action_events_by_courses WS.
|
||||
*/
|
||||
export type AddonCalendarEventsGroupedByCourse = {
|
||||
groupedbycourse: AddonCalendarEventsSameCourse[]; // Groupped by course.
|
||||
};
|
||||
|
||||
/**
|
||||
* Params of core_calendar_get_action_events_by_course WS.
|
||||
*/
|
||||
export type AddonCalendarGetActionEventsByCourseWSParams = {
|
||||
courseid: number; // Course id.
|
||||
timesortfrom?: number; // Time sort from.
|
||||
timesortto?: number; // Time sort to.
|
||||
aftereventid?: number; // The last seen event id.
|
||||
limitnum?: number; // Limit number.
|
||||
searchvalue?: string; // The value a user wishes to search against.
|
||||
};
|
||||
|
||||
/**
|
||||
* Params of core_calendar_get_action_events_by_timesort WS.
|
||||
*/
|
||||
export type AddonCalendarGetActionEventsByTimesortWSParams = {
|
||||
timesortfrom?: number; // Time sort from.
|
||||
timesortto?: number; // Time sort to.
|
||||
aftereventid?: number; // The last seen event id.
|
||||
limitnum?: number; // Limit number.
|
||||
limittononsuspendedevents?: boolean; // Limit the events to courses the user is not suspended in.
|
||||
userid?: number; // The user id.
|
||||
searchvalue?: string; // The value a user wishes to search against.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by calendar's events_same_course_exporter.
|
||||
*/
|
||||
export type AddonCalendarEventsSameCourse = AddonCalendarEvents & {
|
||||
courseid: number; // Courseid.
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by calendar's event_exporter_base.
|
||||
*/
|
||||
|
@ -1889,14 +1828,15 @@ export type AddonCalendarEventBase = {
|
|||
groupname?: string; // Groupname.
|
||||
normalisedeventtype: string; // @since 3.7. Normalisedeventtype.
|
||||
normalisedeventtypetext: string; // @since 3.7. Normalisedeventtypetext.
|
||||
url: string; // Url.
|
||||
purpose?: string; // Purpose. @since 4.0
|
||||
branded?: boolean; // Branded. @since 4.4
|
||||
};
|
||||
|
||||
/**
|
||||
* Data returned by calendar's event_exporter. Don't confuse it with AddonCalendarCalendarEvent.
|
||||
*/
|
||||
export type AddonCalendarEvent = AddonCalendarEventBase & {
|
||||
url: string; // Url.
|
||||
purpose?: string; // Purpose. @since 4.0
|
||||
action?: {
|
||||
name: string; // Name.
|
||||
url: string; // Url.
|
||||
|
@ -1910,7 +1850,6 @@ export type AddonCalendarEvent = AddonCalendarEventBase & {
|
|||
* Data returned by calendar's calendar_event_exporter. Don't confuse it with AddonCalendarEvent.
|
||||
*/
|
||||
export type AddonCalendarCalendarEvent = AddonCalendarEventBase & {
|
||||
url: string; // Url.
|
||||
islastday: boolean; // Islastday.
|
||||
popupname: string; // Popupname.
|
||||
mindaytimestamp?: number; // Mindaytimestamp.
|
||||
|
@ -2124,7 +2063,7 @@ export type AddonCalendarGetCalendarEventsWSResponse = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Event data returned by WS core_calendar_get_calendar_events.
|
||||
* Event data returned by WS core_calendar_get_calendar_events (no exporter used).
|
||||
*/
|
||||
export type AddonCalendarGetEventsEvent = {
|
||||
id: number; // Event id.
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
--color: white;
|
||||
|
||||
@each $type, $value in $activity-icon-background-colors {
|
||||
&.#{$type} {
|
||||
&.#{$type}:not(.branded) {
|
||||
background-color: var(--activity-40-#{$type});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,6 +127,14 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
|
||||
// No icon or local icon (not legacy), colorize it.
|
||||
if (!this.iconUrl || this.isLocalUrl) {
|
||||
|
||||
// Exception for bigbluebuttonbn, it's the only one that has a branded icon.
|
||||
if (this.iconVersion === IconVersion.VERSION_4_0 && this.modname === 'bigbluebuttonbn') {
|
||||
this.isBranded = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.isBranded = false;
|
||||
|
||||
return;
|
||||
|
@ -136,8 +144,8 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
|||
|
||||
// If it's an Moodle Theme icon, check if filtericon is set and use it.
|
||||
if (this.iconUrl && CoreUrlUtils.isThemeImageUrl(this.iconUrl)) {
|
||||
const iconParams = CoreUrlUtils.extractUrlParams(this.iconUrl);
|
||||
if (iconParams['filtericon'] === '1') {
|
||||
const filter = CoreUrlUtils.getThemeImageUrlParam(this.iconUrl, 'filtericon');
|
||||
if (filter === '1') {
|
||||
this.isBranded = false;
|
||||
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue