Merge pull request #4232 from crazyserver/MOBILE-4653

Mobile 4653
main
Dani Palou 2024-11-18 14:46:20 +01:00 committed by GitHub
commit 84781a7658
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
671 changed files with 6508 additions and 4333 deletions

View File

@ -69,7 +69,7 @@ jobs:
cat circular-dependencies cat circular-dependencies
lines=$(cat circular-dependencies | wc -l) lines=$(cat circular-dependencies | wc -l)
echo "Total circular dependencies: $lines" echo "Total circular dependencies: $lines"
test $lines -eq 130 test $lines -eq 90
- name: JavaScript code compatibility - name: JavaScript code compatibility
run: | run: |
npx check-es-compat www/*.js --polyfills="\{Array,String,TypedArray\}.prototype.at,Object.hasOwn" npx check-es-compat www/*.js --polyfills="\{Array,String,TypedArray\}.prototype.at,Object.hasOwn"

View File

@ -30,4 +30,4 @@ const routes: Routes = [
RouterModule.forChild(routes), RouterModule.forChild(routes),
], ],
}) })
export class AddonBadgeLazyModule {} export default class AddonBadgeLazyModule {}

View File

@ -33,4 +33,4 @@ const routes: Routes = [
AddonBadgesBadgeClassPage, AddonBadgesBadgeClassPage,
], ],
}) })
export class AddonBadgeClassLazyModule {} export default class AddonBadgeClassLazyModule {}

View File

@ -63,4 +63,4 @@ const routes: Routes = [
AddonBadgesUserBadgesPage, AddonBadgesUserBadgesPage,
], ],
}) })
export class AddonBadgesLazyModule {} export default class AddonBadgesLazyModule {}

View File

@ -43,15 +43,15 @@ export async function getBadgesServices(): Promise<Type<unknown>[]> {
const mainMenuRoutes: Routes = [ const mainMenuRoutes: Routes = [
{ {
path: 'badge', path: 'badge',
loadChildren: () => import('./badge-lazy.module').then(m => m.AddonBadgeLazyModule), loadChildren: () => import('./badge-lazy.module'),
}, },
{ {
path: 'badges', path: 'badges',
loadChildren: () => import('./badges-lazy.module').then(m => m.AddonBadgesLazyModule), loadChildren: () => import('./badges-lazy.module'),
}, },
{ {
path: 'badgeclass', path: 'badgeclass',
loadChildren: () => import('./badgeclass-lazy.module').then(m => m.AddonBadgeClassLazyModule), loadChildren: () => import('./badgeclass-lazy.module'),
}, },
]; ];

View File

@ -14,7 +14,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
@ -81,7 +81,7 @@ export class AddonBadgesBadgeClassPage implements OnInit {
* @param refresher Refresher. * @param refresher Refresher.
*/ */
async refreshBadgeClass(refresher?: HTMLIonRefresherElement): Promise<void> { async refreshBadgeClass(refresher?: HTMLIonRefresherElement): Promise<void> {
await CoreUtils.ignoreErrors(AddonBadges.invalidateBadgeClass(this.badgeId)); await CorePromiseUtils.ignoreErrors(AddonBadges.invalidateBadgeClass(this.badgeId));
await this.fetchBadgeClass(); await this.fetchBadgeClass();

View File

@ -18,7 +18,7 @@ import { CoreDomUtils } from '@services/utils/dom';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUser } from '@features/user/services/user'; import { CoreUser } from '@features/user/services/user';
import { AddonBadges, AddonBadgesUserBadge } from '../../services/badges'; import { AddonBadges, AddonBadgesUserBadge } from '../../services/badges';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreCourses } from '@features/courses/services/courses'; import { CoreCourses } from '@features/courses/services/courses';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
@ -151,12 +151,12 @@ export class AddonBadgesIssuedBadgePage implements OnInit, OnDestroy {
* @param refresher Refresher. * @param refresher Refresher.
*/ */
async refreshBadges(refresher?: HTMLIonRefresherElement): Promise<void> { async refreshBadges(refresher?: HTMLIonRefresherElement): Promise<void> {
await CoreUtils.allPromisesIgnoringErrors([ await CorePromiseUtils.allPromisesIgnoringErrors([
AddonBadges.invalidateUserBadges(this.courseId, this.userId), AddonBadges.invalidateUserBadges(this.courseId, this.userId),
AddonBadges.invalidateUserBadgeByHash(this.badgeHash), AddonBadges.invalidateUserBadgeByHash(this.badgeHash),
]); ]);
await CoreUtils.ignoreErrors(Promise.all([ await CorePromiseUtils.ignoreErrors(Promise.all([
this.fetchIssuedBadge(), this.fetchIssuedBadge(),
])); ]));

View File

@ -17,7 +17,7 @@ import { AddonBadges, AddonBadgesUserBadge } from '../../services/badges';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreListItemsManager } from '@classes/items-management/list-items-manager'; import { CoreListItemsManager } from '@classes/items-management/list-items-manager';
@ -90,13 +90,13 @@ export class AddonBadgesUserBadgesPage implements AfterViewInit, OnDestroy {
* @param refresher Refresher. * @param refresher Refresher.
*/ */
async refreshBadges(refresher?: HTMLIonRefresherElement): Promise<void> { async refreshBadges(refresher?: HTMLIonRefresherElement): Promise<void> {
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
AddonBadges.invalidateUserBadges( AddonBadges.invalidateUserBadges(
this.badges.getSource().COURSE_ID, this.badges.getSource().COURSE_ID,
this.badges.getSource().USER_ID, this.badges.getSource().USER_ID,
), ),
); );
await CoreUtils.ignoreErrors(this.badges.reload()); await CorePromiseUtils.ignoreErrors(this.badges.reload());
refresher?.complete(); refresher?.complete();
} }

View File

@ -15,9 +15,9 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreWSExternalWarning } from '@services/ws'; import { CoreWSExternalWarning } from '@services/ws';
import { CoreSite } from '@classes/sites/site';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { CoreCacheUpdateFrequency } from '@/core/constants';
const ROOT_CACHE_KEY = 'mmaBadges:'; const ROOT_CACHE_KEY = 'mmaBadges:';
@ -70,7 +70,7 @@ export class AddonBadgesProvider {
}; };
const preSets = { const preSets = {
cacheKey: this.getBadgesCacheKey(courseId, userId), cacheKey: this.getBadgesCacheKey(courseId, userId),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
const response = await site.read<AddonBadgesGetUserBadgesWSResponse>('core_badges_get_user_badges', data, preSets); const response = await site.read<AddonBadgesGetUserBadgesWSResponse>('core_badges_get_user_badges', data, preSets);
@ -133,7 +133,7 @@ export class AddonBadgesProvider {
}; };
const preSets = { const preSets = {
cacheKey: this.getUserBadgeByHashCacheKey(hash), cacheKey: this.getUserBadgeByHashCacheKey(hash),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
const response = await site.read<AddonBadgesGetUserBadgeByHashWSResponse>( const response = await site.read<AddonBadgesGetUserBadgeByHashWSResponse>(
@ -190,7 +190,7 @@ export class AddonBadgesProvider {
}; };
const preSets = { const preSets = {
cacheKey: this.getBadgeClassCacheKey(id), cacheKey: this.getBadgeClassCacheKey(id),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
const response = await site.read<AddonBadgesGetBadgeClassWSResponse>( const response = await site.read<AddonBadgesGetBadgeClassWSResponse>(

View File

@ -14,13 +14,14 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { AddonBadges } from '../badges'; import { AddonBadges } from '../badges';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { AddonBadgesHelper } from '../badges-helper'; import { AddonBadgesHelper } from '../badges-helper';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Handler for badges push notifications clicks. * Handler for badges push notifications clicks.
@ -72,7 +73,7 @@ export class AddonBadgesPushClickHandlerService implements CorePushNotifications
} }
// No hash, open the list of user badges. // No hash, open the list of user badges.
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
AddonBadges.invalidateUserBadges( AddonBadges.invalidateUserBadges(
0, 0,
Number(notification.usertoid), Number(notification.usertoid),

View File

@ -13,7 +13,6 @@
// limitations under the License. // limitations under the License.
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreTagFeedComponent } from '@features/tag/components/feed/feed';
import { CoreTagAreaHandler } from '@features/tag/services/tag-area-delegate'; import { CoreTagAreaHandler } from '@features/tag/services/tag-area-delegate';
import { CoreTagFeedElement, CoreTagHelper } from '@features/tag/services/tag-helper'; import { CoreTagFeedElement, CoreTagHelper } from '@features/tag/services/tag-helper';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
@ -45,7 +44,9 @@ export class AddonBadgesTagAreaHandlerService implements CoreTagAreaHandler {
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown> | Promise<Type<unknown>> { async getComponent(): Promise<Type<unknown>> {
const { CoreTagFeedComponent } = await import('@features/tag/components/feed/feed');
return CoreTagFeedComponent; return CoreTagFeedComponent;
} }

View File

@ -19,7 +19,7 @@ import { CoreBlockBaseComponent } from '@features/block/classes/base-block-compo
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { ContextLevel, CoreConstants } from '@/core/constants'; import { ContextLevel, CoreConstants } from '@/core/constants';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreUtils } from '@services/utils/utils'; import { CoreObject } from '@singletons/object';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreCourseHelper } from '@features/course/services/course-helper'; import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
@ -106,7 +106,7 @@ export class AddonBlockActivityModulesComponent extends CoreBlockBaseComponent i
}); });
// Sort the modnames alphabetically. // Sort the modnames alphabetically.
modFullNames = CoreUtils.sortValues(modFullNames); modFullNames = CoreObject.sortValues(modFullNames);
for (const modName in modFullNames) { for (const modName in modFullNames) {
const iconModName = modName === 'resources' ? 'page' : modName; const iconModName = modName === 'resources' ? 'page' : modName;

View File

@ -19,8 +19,8 @@ import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler
import { CoreCourseBlock } from '@features/course/services/course'; import { CoreCourseBlock } from '@features/course/services/course';
import { Params } from '@angular/router'; import { Params } from '@angular/router';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonCalendarMainMenuHandlerService } from '@addons/calendar/services/handlers/mainmenu';
import { ContextLevel } from '@/core/constants'; import { ContextLevel } from '@/core/constants';
import { ADDON_CALENDAR_PAGE_NAME } from '@addons/calendar/constants';
/** /**
* Block handler. * Block handler.
@ -46,7 +46,7 @@ export class AddonBlockCalendarMonthHandlerService extends CoreBlockBaseHandler
title: 'addon.block_calendarmonth.pluginname', title: 'addon.block_calendarmonth.pluginname',
class: 'addon-block-calendar-month', class: 'addon-block-calendar-month',
component: CoreBlockOnlyTitleComponent, component: CoreBlockOnlyTitleComponent,
link: AddonCalendarMainMenuHandlerService.PAGE_NAME, link: ADDON_CALENDAR_PAGE_NAME,
linkParams: linkParams, linkParams: linkParams,
navOptions: { navOptions: {
preferCurrentTab: false, preferCurrentTab: false,

View File

@ -19,9 +19,9 @@ import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler
import { CoreCourseBlock } from '@features/course/services/course'; import { CoreCourseBlock } from '@features/course/services/course';
import { Params } from '@angular/router'; import { Params } from '@angular/router';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonCalendarMainMenuHandlerService } from '@addons/calendar/services/handlers/mainmenu';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { ContextLevel } from '@/core/constants'; import { ContextLevel } from '@/core/constants';
import { ADDON_CALENDAR_PAGE_NAME } from '@addons/calendar/constants';
/** /**
* Block handler. * Block handler.
@ -51,7 +51,7 @@ export class AddonBlockCalendarUpcomingHandlerService extends CoreBlockBaseHandl
title: 'addon.block_calendarupcoming.pluginname', title: 'addon.block_calendarupcoming.pluginname',
class: 'addon-block-calendar-upcoming', class: 'addon-block-calendar-upcoming',
component: CoreBlockOnlyTitleComponent, component: CoreBlockOnlyTitleComponent,
link: AddonCalendarMainMenuHandlerService.PAGE_NAME, link: ADDON_CALENDAR_PAGE_NAME,
linkParams: linkParams, linkParams: linkParams,
}; };
} }

View File

@ -17,7 +17,6 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { import {
CoreCoursesProvider,
CoreCourses, CoreCourses,
CoreCoursesMyCoursesUpdatedEventData, CoreCoursesMyCoursesUpdatedEventData,
CoreCourseSummaryData, CoreCourseSummaryData,
@ -27,7 +26,7 @@ import { CoreCourseHelper, CorePrefetchStatusInfo } from '@features/course/servi
import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate'; import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate';
import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component'; import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { AddonCourseCompletion } from '@addons/coursecompletion/services/coursecompletion'; import { AddonCourseCompletion } from '@addons/coursecompletion/services/coursecompletion';
@ -38,6 +37,12 @@ import { PageLoadsManager } from '@classes/page-loads-manager';
import { DownloadStatus } from '@/core/constants'; import { DownloadStatus } from '@/core/constants';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { CoreCoursesComponentsModule } from '@features/courses/components/components.module'; import { CoreCoursesComponentsModule } from '@features/courses/components/components.module';
import {
CORE_COURSES_MY_COURSES_UPDATED_EVENT,
CoreCoursesMyCoursesUpdatedEventAction,
CORE_COURSES_STATE_FAVOURITE,
CORE_COURSES_STATE_HIDDEN,
} from '@features/courses/constants';
const FILTER_PRIORITY: AddonBlockMyOverviewTimeFilters[] = const FILTER_PRIORITY: AddonBlockMyOverviewTimeFilters[] =
['all', 'inprogress', 'future', 'past', 'favourite', 'allincludinghidden', 'hidden']; ['all', 'inprogress', 'future', 'past', 'favourite', 'allincludinghidden', 'hidden'];
@ -137,7 +142,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
}, CoreSites.getCurrentSiteId()); }, CoreSites.getCurrentSiteId());
this.coursesObserver = CoreEvents.on( this.coursesObserver = CoreEvents.on(
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, CORE_COURSES_MY_COURSES_UPDATED_EVENT,
(data) => { (data) => {
this.refreshCourseList(data); this.refreshCourseList(data);
}, },
@ -238,7 +243,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
// Invalidate course completion data. // Invalidate course completion data.
promises.push(this.invalidateCourseList().finally(() => promises.push(this.invalidateCourseList().finally(() =>
CoreUtils.allPromises(courseIds.map((courseId) => CorePromiseUtils.allPromises(courseIds.map((courseId) =>
AddonCourseCompletion.invalidateCourseCompletion(courseId))))); AddonCourseCompletion.invalidateCourseCompletion(courseId)))));
if (courseIds.length == 1) { if (courseIds.length == 1) {
@ -250,7 +255,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
promises.push(CoreCourses.invalidateCoursesByField('ids', courseIds.join(','))); promises.push(CoreCourses.invalidateCoursesByField('ids', courseIds.join(',')));
} }
await CoreUtils.allPromises(promises).finally(() => { await CorePromiseUtils.allPromises(promises).finally(() => {
this.prefetchIconsInitialized = false; this.prefetchIconsInitialized = false;
}); });
} }
@ -428,29 +433,29 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
} }
/** /**
* Refresh course list based on a EVENT_MY_COURSES_UPDATED event. * Refresh course list based on a CORE_COURSES_MY_COURSES_UPDATED_EVENT event.
* *
* @param data Event data. * @param data Event data.
* @returns Promise resolved when done. * @returns Promise resolved when done.
*/ */
protected async refreshCourseList(data: CoreCoursesMyCoursesUpdatedEventData): Promise<void> { protected async refreshCourseList(data: CoreCoursesMyCoursesUpdatedEventData): Promise<void> {
if (data.action == CoreCoursesProvider.ACTION_ENROL) { if (data.action === CoreCoursesMyCoursesUpdatedEventAction.ENROL) {
// Always update if user enrolled in a course. // Always update if user enrolled in a course.
return this.refreshContent(true); return this.refreshContent(true);
} }
const course = this.allCourses.find((course) => course.id == data.courseId); const course = this.allCourses.find((course) => course.id == data.courseId);
if (data.action == CoreCoursesProvider.ACTION_STATE_CHANGED) { if (data.action === CoreCoursesMyCoursesUpdatedEventAction.STATE_CHANGED) {
if (!course) { if (!course) {
// Not found, use WS update. // Not found, use WS update.
return this.refreshContent(true); return this.refreshContent(true);
} }
if (data.state == CoreCoursesProvider.STATE_FAVOURITE) { if (data.state === CORE_COURSES_STATE_FAVOURITE) {
course.isfavourite = !!data.value; course.isfavourite = !!data.value;
} }
if (data.state == CoreCoursesProvider.STATE_HIDDEN) { if (data.state === CORE_COURSES_STATE_HIDDEN) {
course.hidden = !!data.value; course.hidden = !!data.value;
} }
@ -458,7 +463,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
await this.filterCourses(); await this.filterCourses();
} }
if (data.action == CoreCoursesProvider.ACTION_VIEW && data.courseId != CoreSites.getCurrentSiteHomeId()) { if (data.action === CoreCoursesMyCoursesUpdatedEventAction.VIEW && data.courseId != CoreSites.getCurrentSiteHomeId()) {
if (!course) { if (!course) {
// Not found, use WS update. // Not found, use WS update.
return this.refreshContent(true); return this.refreshContent(true);

View File

@ -16,7 +16,6 @@ import { Component, OnInit, OnDestroy } from '@angular/core';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { import {
CoreCoursesProvider,
CoreCoursesMyCoursesUpdatedEventData, CoreCoursesMyCoursesUpdatedEventData,
CoreCourses, CoreCourses,
CoreCourseSummaryData, CoreCourseSummaryData,
@ -29,10 +28,16 @@ import {
import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate'; import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate';
import { AddonCourseCompletion } from '@addons/coursecompletion/services/coursecompletion'; import { AddonCourseCompletion } from '@addons/coursecompletion/services/coursecompletion';
import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component'; import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { CoreCoursesComponentsModule } from '@features/courses/components/components.module'; import { CoreCoursesComponentsModule } from '@features/courses/components/components.module';
import {
CORE_COURSES_MY_COURSES_UPDATED_EVENT,
CoreCoursesMyCoursesUpdatedEventAction,
CORE_COURSES_STATE_FAVOURITE,
} from '@features/courses/constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Component to render a recent courses block. * Component to render a recent courses block.
@ -73,7 +78,7 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
this.scrollElementId = `addon-block-recentlyaccessedcourses-scroll-${scrollId}`; this.scrollElementId = `addon-block-recentlyaccessedcourses-scroll-${scrollId}`;
this.coursesObserver = CoreEvents.on( this.coursesObserver = CoreEvents.on(
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, CORE_COURSES_MY_COURSES_UPDATED_EVENT,
(data) => { (data) => {
this.refreshCourseList(data); this.refreshCourseList(data);
}, },
@ -114,7 +119,7 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
// Invalidate course completion data. // Invalidate course completion data.
promises.push(this.invalidateCourseList().finally(() => promises.push(this.invalidateCourseList().finally(() =>
CoreUtils.allPromises(courseIds.map((courseId) => CorePromiseUtils.allPromises(courseIds.map((courseId) =>
AddonCourseCompletion.invalidateCourseCompletion(courseId))))); AddonCourseCompletion.invalidateCourseCompletion(courseId)))));
if (courseIds.length == 1) { if (courseIds.length == 1) {
@ -126,7 +131,7 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
promises.push(CoreCourses.invalidateCoursesByField('ids', courseIds.join(','))); promises.push(CoreCourses.invalidateCoursesByField('ids', courseIds.join(',')));
} }
await CoreUtils.allPromises(promises); await CorePromiseUtils.allPromises(promises);
} }
/** /**
@ -170,20 +175,20 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
} }
/** /**
* Refresh course list based on a EVENT_MY_COURSES_UPDATED event. * Refresh course list based on a CORE_COURSES_MY_COURSES_UPDATED_EVENT event.
* *
* @param data Event data. * @param data Event data.
* @returns Promise resolved when done. * @returns Promise resolved when done.
*/ */
protected async refreshCourseList(data: CoreCoursesMyCoursesUpdatedEventData): Promise<void> { protected async refreshCourseList(data: CoreCoursesMyCoursesUpdatedEventData): Promise<void> {
if (data.action == CoreCoursesProvider.ACTION_ENROL) { if (data.action === CoreCoursesMyCoursesUpdatedEventAction.ENROL) {
// Always update if user enrolled in a course. // Always update if user enrolled in a course.
return this.refreshContent(); return this.refreshContent();
} }
const courseIndex = this.courses.findIndex((course) => course.id == data.courseId); const courseIndex = this.courses.findIndex((course) => course.id == data.courseId);
const course = this.courses[courseIndex]; const course = this.courses[courseIndex];
if (data.action == CoreCoursesProvider.ACTION_VIEW && data.courseId != CoreSites.getCurrentSiteHomeId()) { if (data.action === CoreCoursesMyCoursesUpdatedEventAction.VIEW && data.courseId != CoreSites.getCurrentSiteHomeId()) {
if (!course) { if (!course) {
// Not found, use WS update. // Not found, use WS update.
return this.refreshContent(); return this.refreshContent();
@ -196,8 +201,8 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
await this.invalidateCourseList(); await this.invalidateCourseList();
} }
if (data.action == CoreCoursesProvider.ACTION_STATE_CHANGED && if (data.action === CoreCoursesMyCoursesUpdatedEventAction.STATE_CHANGED &&
data.state == CoreCoursesProvider.STATE_FAVOURITE && course) { data.state === CORE_COURSES_STATE_FAVOURITE && course) {
course.isfavourite = !!data.value; course.isfavourite = !!data.value;
await this.invalidateCourseList(); await this.invalidateCourseList();
} }

View File

@ -21,7 +21,7 @@ import {
} from '../../services/recentlyaccesseditems'; } from '../../services/recentlyaccesseditems';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
/** /**

View File

@ -15,7 +15,7 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreCoursesProvider, CoreCoursesMyCoursesUpdatedEventData, CoreCourses } from '@features/courses/services/courses'; import { CoreCoursesMyCoursesUpdatedEventData, CoreCourses } from '@features/courses/services/courses';
import { import {
CoreCourseSearchedDataWithExtraInfoAndOptions, CoreCourseSearchedDataWithExtraInfoAndOptions,
CoreEnrolledCourseDataWithOptions, CoreEnrolledCourseDataWithOptions,
@ -23,11 +23,17 @@ import {
import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate'; import { CoreCourseOptionsDelegate } from '@features/course/services/course-options-delegate';
import { AddonCourseCompletion } from '@addons/coursecompletion/services/coursecompletion'; import { AddonCourseCompletion } from '@addons/coursecompletion/services/coursecompletion';
import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component'; import { CoreBlockBaseComponent } from '@features/block/classes/base-block-component';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
import { AddonBlockStarredCourse, AddonBlockStarredCourses } from '../../services/starredcourses'; import { AddonBlockStarredCourse, AddonBlockStarredCourses } from '../../services/starredcourses';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { CoreCoursesComponentsModule } from '@features/courses/components/components.module'; import { CoreCoursesComponentsModule } from '@features/courses/components/components.module';
import {
CORE_COURSES_MY_COURSES_UPDATED_EVENT,
CoreCoursesMyCoursesUpdatedEventAction,
CORE_COURSES_STATE_FAVOURITE,
} from '@features/courses/constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Component to render a starred courses block. * Component to render a starred courses block.
@ -68,7 +74,7 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
this.scrollElementId = `addon-block-starredcourses-scroll-${scrollId}`; this.scrollElementId = `addon-block-starredcourses-scroll-${scrollId}`;
this.coursesObserver = CoreEvents.on( this.coursesObserver = CoreEvents.on(
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, CORE_COURSES_MY_COURSES_UPDATED_EVENT,
(data) => { (data) => {
this.refreshCourseList(data); this.refreshCourseList(data);
}, },
@ -108,7 +114,7 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
// Invalidate course completion data. // Invalidate course completion data.
promises.push(this.invalidateCourseList().finally(() => promises.push(this.invalidateCourseList().finally(() =>
CoreUtils.allPromises(courseIds.map((courseId) => CorePromiseUtils.allPromises(courseIds.map((courseId) =>
AddonCourseCompletion.invalidateCourseCompletion(courseId))))); AddonCourseCompletion.invalidateCourseCompletion(courseId)))));
if (courseIds.length == 1) { if (courseIds.length == 1) {
@ -120,7 +126,7 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
promises.push(CoreCourses.invalidateCoursesByField('ids', courseIds.join(','))); promises.push(CoreCourses.invalidateCoursesByField('ids', courseIds.join(',')));
} }
await CoreUtils.allPromises(promises); await CorePromiseUtils.allPromises(promises);
} }
/** /**
@ -157,19 +163,19 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
} }
/** /**
* Refresh course list based on a EVENT_MY_COURSES_UPDATED event. * Refresh course list based on a CORE_COURSES_MY_COURSES_UPDATED_EVENT event.
* *
* @param data Event data. * @param data Event data.
* @returns Promise resolved when done. * @returns Promise resolved when done.
*/ */
protected async refreshCourseList(data: CoreCoursesMyCoursesUpdatedEventData): Promise<void> { protected async refreshCourseList(data: CoreCoursesMyCoursesUpdatedEventData): Promise<void> {
if (data.action == CoreCoursesProvider.ACTION_ENROL) { if (data.action === CoreCoursesMyCoursesUpdatedEventAction.ENROL) {
// Always update if user enrolled in a course. // Always update if user enrolled in a course.
// New courses shouldn't be favourite by default, but just in case. // New courses shouldn't be favourite by default, but just in case.
return this.refreshContent(); return this.refreshContent();
} }
if (data.action == CoreCoursesProvider.ACTION_STATE_CHANGED && data.state == CoreCoursesProvider.STATE_FAVOURITE) { if (data.action === CoreCoursesMyCoursesUpdatedEventAction.STATE_CHANGED && data.state == CORE_COURSES_STATE_FAVOURITE) {
const courseIndex = this.courses.findIndex((course) => course.id == data.courseId); const courseIndex = this.courses.findIndex((course) => course.id == data.courseId);
if (courseIndex < 0) { if (courseIndex < 0) {
// Not found, use WS update. Usually new favourite. // Not found, use WS update. Usually new favourite.

View File

@ -16,7 +16,7 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { ICoreBlockComponent } from '@features/block/classes/base-block-component'; import { ICoreBlockComponent } from '@features/block/classes/base-block-component';
import { AddonBlockTimeline } from '../../services/timeline'; import { AddonBlockTimeline } from '../../services/timeline';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreCoursesHelper, CoreEnrolledCourseDataWithOptions } from '@features/courses/services/courses-helper'; import { CoreCoursesHelper, CoreEnrolledCourseDataWithOptions } from '@features/courses/services/courses-helper';
import { CoreCourses } from '@features/courses/services/courses'; import { CoreCourses } from '@features/courses/services/courses';
@ -122,7 +122,7 @@ export class AddonBlockTimelineComponent implements OnInit, ICoreBlockComponent
* @inheritdoc * @inheritdoc
*/ */
async invalidateContent(): Promise<void> { async invalidateContent(): Promise<void> {
await CoreUtils.allPromises([ await CorePromiseUtils.allPromises([
AddonBlockTimeline.invalidateActionEventsByTimesort(), AddonBlockTimeline.invalidateActionEventsByTimesort(),
AddonBlockTimeline.invalidateActionEventsByCourses(), AddonBlockTimeline.invalidateActionEventsByCourses(),
CoreCourses.invalidateUserCourses(), CoreCourses.invalidateUserCourses(),

View File

@ -42,7 +42,7 @@ import { canLeaveGuard } from '@guards/can-leave';
}, },
{ {
path: 'edit/:id', path: 'edit/:id',
loadComponent: () => import('./pages/edit-entry/edit-entry').then(c => c.AddonBlogEditEntryPage), loadComponent: () => import('./pages/edit-entry/edit-entry'),
canDeactivate: [canLeaveGuard], canDeactivate: [canLeaveGuard],
}, },
...buildTabMainRoutes(injector, { ...buildTabMainRoutes(injector, {
@ -71,4 +71,4 @@ import { canLeaveGuard } from '@guards/can-leave';
}, },
], ],
}) })
export class AddonBlogLazyModule {} export default class AddonBlogLazyModule {}

View File

@ -37,7 +37,7 @@ import { AddonBlogSyncCronHandler } from './services/handlers/sync-cron';
const routes: Routes = [ const routes: Routes = [
{ {
path: ADDON_BLOG_MAINMENU_PAGE_NAME, path: ADDON_BLOG_MAINMENU_PAGE_NAME,
loadChildren: () => import('@addons/blog/blog-lazy.module').then(m => m.AddonBlogLazyModule), loadChildren: () => import('@addons/blog/blog-lazy.module'),
}, },
]; ];

View File

@ -41,12 +41,13 @@ import { CoreNetwork } from '@services/network';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreSync } from '@services/sync'; import { CoreSync } from '@services/sync';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreWSError } from '@classes/errors/wserror';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreForms } from '@singletons/form'; import { CoreForms } from '@singletons/form';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CorePromiseUtils } from '@singletons/promise-utils';
@Component({ @Component({
selector: 'addon-blog-edit-entry', selector: 'addon-blog-edit-entry',
@ -59,7 +60,7 @@ import { CoreTimeUtils } from '@services/utils/time';
CoreTagComponentsModule, CoreTagComponentsModule,
], ],
}) })
export class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestroy { export default class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestroy {
@ViewChild('editEntryForm') formElement!: ElementRef; @ViewChild('editEntryForm') formElement!: ElementRef;
@ -257,7 +258,7 @@ export class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestroy {
return selectedEntry; return selectedEntry;
} catch (error) { } catch (error) {
if (!params.filters || CoreUtils.isWebServiceError(error)) { if (!params.filters || CoreWSError.isWebServiceError(error)) {
// Cannot get the entry, reject. // Cannot get the entry, reject.
throw error; throw error;
} }
@ -323,7 +324,7 @@ export class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestroy {
const filters: AddonBlogFilter | undefined = CoreNavigator.getRouteParam('filters'); const filters: AddonBlogFilter | undefined = CoreNavigator.getRouteParam('filters');
const entry = this.entry && 'attachment' in this.entry const entry = this.entry && 'attachment' in this.entry
? this.entry ? this.entry
: await CoreUtils.ignoreErrors(this.getEntry({ filters, lastModified, entryId: this.entry.id })); : await CorePromiseUtils.ignoreErrors(this.getEntry({ filters, lastModified, entryId: this.entry.id }));
const removedFiles = CoreFileUploader.getFilesToDelete(entry?.attachmentfiles ?? [], this.files); const removedFiles = CoreFileUploader.getFilesToDelete(entry?.attachmentfiles ?? [], this.files);
@ -335,7 +336,7 @@ export class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestroy {
return await this.saveEntry({ attachmentsId: attachmentsid }); return await this.saveEntry({ attachmentsId: attachmentsid });
} catch (error) { } catch (error) {
if (CoreUtils.isWebServiceError(error)) { if (CoreWSError.isWebServiceError(error)) {
// It's a WebService error, the user cannot send the message so don't store it. // It's a WebService error, the user cannot send the message so don't store it.
CoreDomUtils.showErrorModalDefault(error, 'Error updating entry.'); CoreDomUtils.showErrorModalDefault(error, 'Error updating entry.');
@ -360,7 +361,7 @@ export class AddonBlogEditEntryPage implements CanLeave, OnInit, OnDestroy {
const attachmentsId = await this.uploadOrStoreFiles({ created }); const attachmentsId = await this.uploadOrStoreFiles({ created });
await this.saveEntry({ created, attachmentsId }); await this.saveEntry({ created, attachmentsId });
} catch (error) { } catch (error) {
if (CoreUtils.isWebServiceError(error)) { if (CoreWSError.isWebServiceError(error)) {
// It's a WebService error, the user cannot send the message so don't store it. // It's a WebService error, the user cannot send the message so don't store it.
CoreDomUtils.showErrorModalDefault(error, 'Error creating entry.'); CoreDomUtils.showErrorModalDefault(error, 'Error creating entry.');

View File

@ -36,7 +36,7 @@ import { CoreNetwork } from '@services/network';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreArray } from '@singletons/array'; import { CoreArray } from '@singletons/array';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreTime } from '@singletons/time'; import { CoreTime } from '@singletons/time';
@ -93,7 +93,7 @@ export class AddonBlogIndexPage implements OnInit, OnDestroy {
this.isOnline.set(CoreNetwork.isOnline()); this.isOnline.set(CoreNetwork.isOnline());
this.logView = CoreTime.once(async () => { this.logView = CoreTime.once(async () => {
await CoreUtils.ignoreErrors(AddonBlog.logView(this.filter)); await CorePromiseUtils.ignoreErrors(AddonBlog.logView(this.filter));
CoreAnalytics.logEvent({ CoreAnalytics.logEvent({
type: CoreAnalyticsEventType.VIEW_ITEM_LIST, type: CoreAnalyticsEventType.VIEW_ITEM_LIST,
@ -113,7 +113,7 @@ export class AddonBlogIndexPage implements OnInit, OnDestroy {
this.entryUpdateObserver = CoreEvents.on(ADDON_BLOG_ENTRY_UPDATED, async () => { this.entryUpdateObserver = CoreEvents.on(ADDON_BLOG_ENTRY_UPDATED, async () => {
this.loaded.set(false); this.loaded.set(false);
await CoreUtils.ignoreErrors(this.refresh()); await CorePromiseUtils.ignoreErrors(this.refresh());
this.loaded.set(true); this.loaded.set(true);
}); });
@ -123,7 +123,7 @@ export class AddonBlogIndexPage implements OnInit, OnDestroy {
} }
this.loaded.set(false); this.loaded.set(false);
await CoreUtils.ignoreErrors(this.refresh(false)); await CorePromiseUtils.ignoreErrors(this.refresh(false));
this.loaded.set(true); this.loaded.set(true);
}); });
@ -375,7 +375,7 @@ export class AddonBlogIndexPage implements OnInit, OnDestroy {
* @param refresher Refresher instance. * @param refresher Refresher instance.
*/ */
async refresh(sync = true, refresher?: HTMLIonRefresherElement): Promise<void> { async refresh(sync = true, refresher?: HTMLIonRefresherElement): Promise<void> {
const promises = this.entries.map((entry) => { const promises = this.entries.map(async (entry) => {
if (this.isOnlineEntry(entry)) { if (this.isOnlineEntry(entry)) {
return CoreComments.invalidateCommentsData( return CoreComments.invalidateCommentsData(
ContextLevel.USER, ContextLevel.USER,
@ -399,7 +399,7 @@ export class AddonBlogIndexPage implements OnInit, OnDestroy {
} }
await CoreUtils.allPromises(promises); await CorePromiseUtils.allPromises(promises);
await this.fetchEntries(true, false, sync); await this.fetchEntries(true, false, sync);
refresher?.complete(); refresher?.complete();
} }

View File

@ -17,7 +17,7 @@ import { CoreFileUploader } from '@features/fileuploader/services/fileuploader';
import { CoreFile } from '@services/file'; import { CoreFile } from '@services/file';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreObject } from '@singletons/object'; import { CoreObject } from '@singletons/object';
import { CorePath } from '@singletons/path'; import { CorePath } from '@singletons/path';
@ -108,7 +108,7 @@ export class AddonBlogOfflineService {
*/ */
async getOfflineEntry(filter: { id?: number; created?: number }, siteId?: string): Promise<AddonBlogOfflineEntry | undefined> { async getOfflineEntry(filter: { id?: number; created?: number }, siteId?: string): Promise<AddonBlogOfflineEntry | undefined> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
const record = await CoreUtils.ignoreErrors( const record = await CorePromiseUtils.ignoreErrors(
site.getDb().getRecord<AddonBlogOfflineEntry>(OFFLINE_BLOG_ENTRIES_TABLE_NAME, filter), site.getDb().getRecord<AddonBlogOfflineEntry>(OFFLINE_BLOG_ENTRIES_TABLE_NAME, filter),
); );

View File

@ -17,7 +17,7 @@ import { CoreSyncBaseProvider, CoreSyncBlockedError } from '@classes/base-sync';
import { CoreFileUploader } from '@features/fileuploader/services/fileuploader'; import { CoreFileUploader } from '@features/fileuploader/services/fileuploader';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreSync, CoreSyncResult } from '@services/sync'; import { CoreSync, CoreSyncResult } from '@services/sync';
import { CoreUtils } from '@services/utils/utils'; import { CoreWSError } from '@classes/errors/wserror';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { ADDON_BLOG_AUTO_SYNCED, ADDON_BLOG_SYNC_ID } from '../constants'; import { ADDON_BLOG_AUTO_SYNCED, ADDON_BLOG_SYNC_ID } from '../constants';
@ -129,7 +129,7 @@ import { AddonBlogOfflineEntryDBRecord } from './database/blog';
await AddonBlogOffline.deleteOfflineEntryRecord({ created: entry.created }, siteId); await AddonBlogOffline.deleteOfflineEntryRecord({ created: entry.created }, siteId);
result.updated = true; result.updated = true;
} catch (error) { } catch (error) {
if (!error || !CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
throw error; throw error;
} }
@ -223,7 +223,7 @@ import { AddonBlogOfflineEntryDBRecord } from './database/blog';
entriesToSync = entriesPendingToSync; entriesToSync = entriesPendingToSync;
} }
} catch (error) { } catch (error) {
if (!CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
throw error; throw error;
} }

View File

@ -12,10 +12,9 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { ContextLevel } from '@/core/constants'; import { ContextLevel, CoreCacheUpdateFrequency } from '@/core/constants';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreSite } from '@classes/sites/site';
import { CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader'; import { CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader';
import { CoreTagItem } from '@features/tag/services/tag'; import { CoreTagItem } from '@features/tag/services/tag';
import { CoreUser, CoreUserProfile } from '@features/user/services/user'; import { CoreUser, CoreUserProfile } from '@features/user/services/user';
@ -23,10 +22,12 @@ import { CoreFileEntry, CoreFileHelper } from '@services/file-helper';
import { CoreNetwork } from '@services/network'; import { CoreNetwork } from '@services/network';
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites'; import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils'; import { CoreObject } from '@singletons/object';
import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws'; import { CoreStatusWithWarningsWSResponse, CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonBlogOffline, AddonBlogOfflineEntry } from './blog-offline'; import { AddonBlogOffline, AddonBlogOfflineEntry } from './blog-offline';
import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreWSError } from '@classes/errors/wserror';
const ROOT_CACHE_KEY = 'addonBlog:'; const ROOT_CACHE_KEY = 'addonBlog:';
@ -62,7 +63,7 @@ export class AddonBlogProvider {
* @returns Cache key. * @returns Cache key.
*/ */
getEntriesCacheKey(filter: AddonBlogFilter = {}): string { getEntriesCacheKey(filter: AddonBlogFilter = {}): string {
return ROOT_CACHE_KEY + CoreUtils.sortAndStringify(filter); return ROOT_CACHE_KEY + CoreObject.sortAndStringify(filter);
} }
/** /**
@ -76,14 +77,14 @@ export class AddonBlogProvider {
const site = await CoreSites.getSite(options?.siteId); const site = await CoreSites.getSite(options?.siteId);
const data: CoreBlogGetEntriesWSParams = { const data: CoreBlogGetEntriesWSParams = {
filters: CoreUtils.objectToArrayOfObjects(filter, 'name', 'value'), filters: CoreObject.toArrayOfObjects(filter, 'name', 'value'),
page: options?.page ?? 0, page: options?.page ?? 0,
perpage: AddonBlogProvider.ENTRIES_PER_PAGE, perpage: AddonBlogProvider.ENTRIES_PER_PAGE,
}; };
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getEntriesCacheKey(filter), cacheKey: this.getEntriesCacheKey(filter),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
...CoreSites.getReadingStrategyPreSets(options?.readingStrategy), ...CoreSites.getReadingStrategyPreSets(options?.readingStrategy),
}; };
@ -121,7 +122,7 @@ export class AddonBlogProvider {
try { try {
await this.addEntryOnline(params, siteId); await this.addEntryOnline(params, siteId);
} catch (error) { } catch (error) {
if (!CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return await storeOffline(); return await storeOffline();
} }
@ -177,7 +178,7 @@ export class AddonBlogProvider {
try { try {
await this.updateEntryOnline(params, siteId); await this.updateEntryOnline(params, siteId);
} catch (error) { } catch (error) {
if (!CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return await storeOffline(); return await storeOffline();
} }
@ -230,9 +231,9 @@ export class AddonBlogProvider {
} }
await this.deleteEntryOnline(params, siteId); await this.deleteEntryOnline(params, siteId);
await CoreUtils.ignoreErrors(AddonBlogOffline.unmarkEntryAsRemoved(params.entryid)); await CorePromiseUtils.ignoreErrors(AddonBlogOffline.unmarkEntryAsRemoved(params.entryid));
} catch (error) { } catch (error) {
if (!CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return await AddonBlogOffline.markEntryAsRemoved({ id: params.entryid, subject }, siteId); return await AddonBlogOffline.markEntryAsRemoved({ id: params.entryid, subject }, siteId);
} }
@ -289,7 +290,7 @@ export class AddonBlogProvider {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
const data: AddonBlogViewEntriesWSParams = { const data: AddonBlogViewEntriesWSParams = {
filters: CoreUtils.objectToArrayOfObjects(filter, 'name', 'value'), filters: CoreObject.toArrayOfObjects(filter, 'name', 'value'),
}; };
return site.write('core_blog_view_entries', data); return site.write('core_blog_view_entries', data);
@ -312,7 +313,7 @@ export class AddonBlogProvider {
const tags = options?.find(option => option.name === 'tags')?.value as string | undefined; const tags = options?.find(option => option.name === 'tags')?.value as string | undefined;
const publishState = options?.find(option => option.name === 'publishstate')?.value as AddonBlogPublishState const publishState = options?.find(option => option.name === 'publishstate')?.value as AddonBlogPublishState
?? AddonBlogPublishState.draft; ?? AddonBlogPublishState.draft;
const user = await CoreUtils.ignoreErrors(CoreUser.getProfile(offlineEntry.userid, courseId, true)); const user = await CorePromiseUtils.ignoreErrors(CoreUser.getProfile(offlineEntry.userid, courseId, true));
const folder = 'id' in offlineEntry && offlineEntry.id ? { id: offlineEntry.id } : { created: offlineEntry.created }; const folder = 'id' in offlineEntry && offlineEntry.id ? { id: offlineEntry.id } : { created: offlineEntry.created };
const offlineFiles = await AddonBlogOffline.getOfflineFiles(folder); const offlineFiles = await AddonBlogOffline.getOfflineFiles(folder);
const optionsFiles = this.getAttachmentFilesFromOptions(options); const optionsFiles = this.getAttachmentFilesFromOptions(options);
@ -376,7 +377,7 @@ export class AddonBlogProvider {
} }
entry.summary = CoreFileHelper.replacePluginfileUrls(entry.summary, entry.summaryfiles || []); entry.summary = CoreFileHelper.replacePluginfileUrls(entry.summary, entry.summaryfiles || []);
entry.user = await CoreUtils.ignoreErrors(CoreUser.getProfile(entry.userid, entry.courseid, true)); entry.user = await CorePromiseUtils.ignoreErrors(CoreUser.getProfile(entry.userid, entry.courseid, true));
} }
/** /**

View File

@ -13,7 +13,6 @@
// limitations under the License. // limitations under the License.
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreTagFeedComponent } from '@features/tag/components/feed/feed';
import { CoreTagAreaHandler } from '@features/tag/services/tag-area-delegate'; import { CoreTagAreaHandler } from '@features/tag/services/tag-area-delegate';
import { CoreTagFeedElement, CoreTagHelper } from '@features/tag/services/tag-helper'; import { CoreTagFeedElement, CoreTagHelper } from '@features/tag/services/tag-helper';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
@ -45,7 +44,9 @@ export class AddonBlogTagAreaHandlerService implements CoreTagAreaHandler {
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<unknown> | Promise<Type<unknown>> { async getComponent(): Promise<Type<unknown>> {
const { CoreTagFeedComponent } = await import('@features/tag/components/feed/feed');
return CoreTagFeedComponent; return CoreTagFeedComponent;
} }

View File

@ -25,7 +25,7 @@ import { CoreEditorComponentsModule } from '@features/editor/components/componen
import { CoreMainMenuComponentsModule } from '@features/mainmenu/components/components.module'; import { CoreMainMenuComponentsModule } from '@features/mainmenu/components/components.module';
import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module'; import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
import { AddonCalendarMainMenuHandlerService } from './services/handlers/mainmenu'; import { ADDON_CALENDAR_PAGE_NAME } from './constants';
/** /**
* Build module routes. * Build module routes.
@ -37,7 +37,7 @@ function buildRoutes(injector: Injector): Routes {
return [ return [
{ {
path: 'index', path: 'index',
data: { mainMenuTabRoot: AddonCalendarMainMenuHandlerService.PAGE_NAME }, data: { mainMenuTabRoot: ADDON_CALENDAR_PAGE_NAME },
component: AddonCalendarIndexPage, component: AddonCalendarIndexPage,
}, },
{ {
@ -86,4 +86,4 @@ function buildRoutes(injector: Injector): Routes {
}, },
], ],
}) })
export class AddonCalendarLazyModule {} export default class AddonCalendarLazyModule {}

View File

@ -20,7 +20,7 @@ import { CoreMainMenuDelegate } from '@features/mainmenu/services/mainmenu-deleg
import { CoreCronDelegate } from '@services/cron'; import { CoreCronDelegate } from '@services/cron';
import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate'; import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate';
import { AddonCalendarViewLinkHandler } from './services/handlers/view-link'; import { AddonCalendarViewLinkHandler } from './services/handlers/view-link';
import { AddonCalendarMainMenuHandler, AddonCalendarMainMenuHandlerService } from './services/handlers/mainmenu'; import { AddonCalendarMainMenuHandler } from './services/handlers/mainmenu';
import { AddonCalendarSyncCronHandler } from './services/handlers/sync-cron'; import { AddonCalendarSyncCronHandler } from './services/handlers/sync-cron';
import { CORE_SITE_SCHEMAS } from '@services/sites'; import { CORE_SITE_SCHEMAS } from '@services/sites';
@ -29,6 +29,7 @@ import { CALENDAR_OFFLINE_SITE_SCHEMA } from './services/database/calendar-offli
import { AddonCalendarComponentsModule } from './components/components.module'; import { AddonCalendarComponentsModule } from './components/components.module';
import { AddonCalendar } from './services/calendar'; import { AddonCalendar } from './services/calendar';
import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module'; import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module';
import { ADDON_CALENDAR_PAGE_NAME } from './constants';
/** /**
* Get calendar services. * Get calendar services.
@ -51,8 +52,8 @@ export async function getCalendarServices(): Promise<Type<unknown>[]> {
const mainMenuChildrenRoutes: Routes = [ const mainMenuChildrenRoutes: Routes = [
{ {
path: AddonCalendarMainMenuHandlerService.PAGE_NAME, path: ADDON_CALENDAR_PAGE_NAME,
loadChildren: () => import('./calendar-lazy.module').then(m => m.AddonCalendarLazyModule), loadChildren: () => import('./calendar-lazy.module'),
}, },
]; ];

View File

@ -29,10 +29,9 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils'; import { CoreArray } from '@singletons/array';
import { import {
AddonCalendar, AddonCalendar,
AddonCalendarProvider,
AddonCalendarWeek, AddonCalendarWeek,
AddonCalendarWeekDaysTranslationKeys, AddonCalendarWeekDaysTranslationKeys,
AddonCalendarEventToDisplay, AddonCalendarEventToDisplay,
@ -54,6 +53,7 @@ import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time'; import { CoreTime } from '@singletons/time';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { toBoolean } from '@/core/transforms/boolean'; import { toBoolean } from '@/core/transforms/boolean';
import { ADDON_CALENDAR_UNDELETED_EVENT_EVENT } from '@addons/calendar/constants';
/** /**
* Component that displays a calendar. * Component that displays a calendar.
@ -61,7 +61,7 @@ import { toBoolean } from '@/core/transforms/boolean';
@Component({ @Component({
selector: 'addon-calendar-calendar', selector: 'addon-calendar-calendar',
templateUrl: 'addon-calendar-calendar.html', templateUrl: 'addon-calendar-calendar.html',
styleUrls: ['calendar.scss'], styleUrl: 'calendar.scss',
}) })
export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestroy { export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestroy {
@ -93,7 +93,7 @@ export class AddonCalendarCalendarComponent implements OnInit, DoCheck, OnDestro
// Listen for events "undeleted" (offline). // Listen for events "undeleted" (offline).
this.undeleteEventObserver = CoreEvents.on( this.undeleteEventObserver = CoreEvents.on(
AddonCalendarProvider.UNDELETED_EVENT_EVENT, ADDON_CALENDAR_UNDELETED_EVENT_EVENT,
(data) => { (data) => {
if (!data || !data.eventId) { if (!data || !data.eventId) {
return; return;
@ -464,7 +464,7 @@ class AddonCalendarMonthSlidesItemsManagerSource extends CoreSwipeSlidesDynamicI
const categories = await CoreCourses.getCategories(0, true); const categories = await CoreCourses.getCategories(0, true);
// Index categories by ID. // Index categories by ID.
this.categories = CoreUtils.arrayToObject(categories, 'id'); this.categories = CoreArray.toObject(categories, 'id');
} catch { } catch {
// Ignore errors. // Ignore errors.
} }

View File

@ -14,13 +14,13 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { CoreEnrolledCourseData } from '@features/courses/services/courses'; import { CoreEnrolledCourseData } from '@features/courses/services/courses';
import { CoreUtils } from '@services/utils/utils'; import { CoreObject } from '@singletons/object';
import { ModalController } from '@singletons'; import { ModalController } from '@singletons';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { AddonCalendarEventType, AddonCalendarProvider } from '../../services/calendar'; import { AddonCalendarFilter } from '@addons/calendar/services/calendar-helper';
import { AddonCalendarFilter, AddonCalendarEventIcons } from '../../services/calendar-helper';
import { ALL_COURSES_ID } from '@features/courses/services/courses-helper'; import { ALL_COURSES_ID } from '@features/courses/services/courses-helper';
import { CoreSharedModule } from '@/core/shared.module'; import { CoreSharedModule } from '@/core/shared.module';
import { ADDON_CALENDAR_FILTER_CHANGED_EVENT, AddonCalendarEventIcons, AddonCalendarEventType } from '@addons/calendar/constants';
/** /**
* Component to display the events filter that includes events types and a list of courses. * Component to display the events filter that includes events types and a list of courses.
@ -54,7 +54,7 @@ export class AddonCalendarFilterComponent implements OnInit {
sortedCourses: CoreEnrolledCourseData[] = []; sortedCourses: CoreEnrolledCourseData[] = [];
constructor() { constructor() {
CoreUtils.enumKeys(AddonCalendarEventType).forEach((name) => { CoreObject.enumKeys(AddonCalendarEventType).forEach((name) => {
const value = AddonCalendarEventType[name]; const value = AddonCalendarEventType[name];
this.typeIcons[value] = AddonCalendarEventIcons[name]; this.typeIcons[value] = AddonCalendarEventIcons[name];
this.types.push(value); this.types.push(value);
@ -95,7 +95,7 @@ export class AddonCalendarFilterComponent implements OnInit {
this.filter.filtered = !!this.filter.courseId || this.types.some((name) => !this.filter[name]); this.filter.filtered = !!this.filter.courseId || this.types.some((name) => !this.filter[name]);
CoreEvents.trigger(AddonCalendarProvider.FILTER_CHANGED_EVENT, this.filter); CoreEvents.trigger(ADDON_CALENDAR_FILTER_CHANGED_EVENT, this.filter);
} }
/** /**

View File

@ -17,7 +17,6 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { import {
AddonCalendarProvider,
AddonCalendarEventToDisplay, AddonCalendarEventToDisplay,
AddonCalendar, AddonCalendar,
} from '../../services/calendar'; } from '../../services/calendar';
@ -29,6 +28,7 @@ import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time'; import { CoreTime } from '@singletons/time';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { ADDON_CALENDAR_UNDELETED_EVENT_EVENT } from '@addons/calendar/constants';
/** /**
* Component that displays upcoming events. * Component that displays upcoming events.
@ -36,7 +36,7 @@ import { Translate } from '@singletons';
@Component({ @Component({
selector: 'addon-calendar-upcoming-events', selector: 'addon-calendar-upcoming-events',
templateUrl: 'addon-calendar-upcoming-events.html', templateUrl: 'addon-calendar-upcoming-events.html',
styleUrls: ['../../calendar-common.scss'], styleUrl: '../../calendar-common.scss',
}) })
export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, OnDestroy { export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, OnDestroy {
@ -70,7 +70,7 @@ export class AddonCalendarUpcomingEventsComponent implements OnInit, DoCheck, On
// Listen for events "undeleted" (offline). // Listen for events "undeleted" (offline).
this.undeleteEventObserver = CoreEvents.on( this.undeleteEventObserver = CoreEvents.on(
AddonCalendarProvider.UNDELETED_EVENT_EVENT, ADDON_CALENDAR_UNDELETED_EVENT_EVENT,
(data) => { (data) => {
if (!data || !data.eventId) { if (!data || !data.eventId) {
return; return;

View File

@ -13,3 +13,46 @@
// limitations under the License. // limitations under the License.
export const ADDON_CALENDAR_COMPONENT = 'AddonCalendarEvents'; export const ADDON_CALENDAR_COMPONENT = 'AddonCalendarEvents';
export const ADDON_CALENDAR_PAGE_NAME = 'calendar';
export const ADDON_CALENDAR_EVENTS_TABLE = 'addon_calendar_events_3';
export const ADDON_CALENDAR_AUTO_SYNCED = 'addon_calendar_autom_synced';
export const ADDON_CALENDAR_MANUAL_SYNCED = 'addon_calendar_manual_synced';
export const ADDON_CALENDAR_SYNC_ID = 'calendar';
export const ADDON_CALENDAR_DAYS_INTERVAL = 30;
export const ADDON_CALENDAR_STARTING_WEEK_DAY = 'addon_calendar_starting_week_day';
export const ADDON_CALENDAR_TF_24 = '%H:%M'; // Calendar time in 24 hours format.
export const ADDON_CALENDAR_TF_12 = '%I:%M %p'; // Calendar time in 12 hours format.
export const ADDON_CALENDAR_NEW_EVENT_EVENT = 'addon_calendar_new_event';
export const ADDON_CALENDAR_NEW_EVENT_DISCARDED_EVENT = 'addon_calendar_new_event_discarded';
export const ADDON_CALENDAR_EDIT_EVENT_EVENT = 'addon_calendar_edit_event';
export const ADDON_CALENDAR_DELETED_EVENT_EVENT = 'addon_calendar_deleted_event';
export const ADDON_CALENDAR_UNDELETED_EVENT_EVENT = 'addon_calendar_undeleted_event';
export const ADDON_CALENDAR_FILTER_CHANGED_EVENT = 'addon_calendar_filter_changed_event';
/**
* Context levels enumeration.
*/
export enum AddonCalendarEventIcons {
SITE = 'fas-globe',
CATEGORY = 'fas-cubes',
COURSE = 'fas-graduation-cap',
GROUP = 'fas-users',
USER = 'fas-user',
}
/**
* Main calendar Event types enumeration.
*/
export enum AddonCalendarEventType {
SITE = 'site',
CATEGORY = 'category',
COURSE = 'course',
GROUP = 'group',
USER = 'user',
}

View File

@ -19,15 +19,13 @@ import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { import {
AddonCalendarProvider,
AddonCalendar, AddonCalendar,
AddonCalendarEventToDisplay, AddonCalendarEventToDisplay,
AddonCalendarCalendarDay, AddonCalendarCalendarDay,
AddonCalendarEventType,
} from '../../services/calendar'; } from '../../services/calendar';
import { AddonCalendarOffline } from '../../services/calendar-offline'; import { AddonCalendarOffline } from '../../services/calendar-offline';
import { AddonCalendarFilter, AddonCalendarHelper } from '../../services/calendar-helper'; import { AddonCalendarFilter, AddonCalendarHelper } from '../../services/calendar-helper';
import { AddonCalendarSync, AddonCalendarSyncProvider } from '../../services/calendar-sync'; import { AddonCalendarSync } from '../../services/calendar-sync';
import { CoreCategoryData, CoreCourses, CoreEnrolledCourseData } from '@features/courses/services/courses'; import { CoreCategoryData, CoreCourses, CoreEnrolledCourseData } from '@features/courses/services/courses';
import { CoreCoursesHelper } from '@features/courses/services/courses-helper'; import { CoreCoursesHelper } from '@features/courses/services/courses-helper';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
@ -35,7 +33,7 @@ import { NgZone, Translate } from '@singletons';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { Params } from '@angular/router'; import { Params } from '@angular/router';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { CoreUtils } from '@services/utils/utils'; import { CoreArray } from '@singletons/array';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreSwipeSlidesDynamicItemsManager } from '@classes/items-management/swipe-slides-dynamic-items-manager'; import { CoreSwipeSlidesDynamicItemsManager } from '@classes/items-management/swipe-slides-dynamic-items-manager';
import { CoreSwipeSlidesComponent } from '@components/swipe-slides/swipe-slides'; import { CoreSwipeSlidesComponent } from '@components/swipe-slides/swipe-slides';
@ -49,6 +47,18 @@ import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import { CoreTime } from '@singletons/time'; import { CoreTime } from '@singletons/time';
import { CoreModals } from '@services/modals'; import { CoreModals } from '@services/modals';
import {
ADDON_CALENDAR_AUTO_SYNCED,
ADDON_CALENDAR_DELETED_EVENT_EVENT,
ADDON_CALENDAR_EDIT_EVENT_EVENT,
ADDON_CALENDAR_FILTER_CHANGED_EVENT,
ADDON_CALENDAR_MANUAL_SYNCED,
ADDON_CALENDAR_NEW_EVENT_DISCARDED_EVENT,
ADDON_CALENDAR_NEW_EVENT_EVENT,
ADDON_CALENDAR_UNDELETED_EVENT_EVENT,
AddonCalendarEventType,
} from '@addons/calendar/constants';
import { CoreObject } from '@singletons/object';
/** /**
* Page that displays the calendar events for a certain day. * Page that displays the calendar events for a certain day.
@ -91,7 +101,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
// Listen for events added. When an event is added, reload the data. // Listen for events added. When an event is added, reload the data.
this.eventObservers.push(CoreEvents.on( this.eventObservers.push(CoreEvents.on(
AddonCalendarProvider.NEW_EVENT_EVENT, ADDON_CALENDAR_NEW_EVENT_EVENT,
(data) => { (data) => {
if (data && data.eventId) { if (data && data.eventId) {
this.manager?.getSource().markAllItemsUnloaded(); this.manager?.getSource().markAllItemsUnloaded();
@ -102,14 +112,14 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
)); ));
// Listen for new event discarded event. When it does, reload the data. // Listen for new event discarded event. When it does, reload the data.
this.eventObservers.push(CoreEvents.on(AddonCalendarProvider.NEW_EVENT_DISCARDED_EVENT, () => { this.eventObservers.push(CoreEvents.on(ADDON_CALENDAR_NEW_EVENT_DISCARDED_EVENT, () => {
this.manager?.getSource().markAllItemsUnloaded(); this.manager?.getSource().markAllItemsUnloaded();
this.refreshData(true, true); this.refreshData(true, true);
}, this.currentSiteId)); }, this.currentSiteId));
// Listen for events edited. When an event is edited, reload the data. // Listen for events edited. When an event is edited, reload the data.
this.eventObservers.push(CoreEvents.on( this.eventObservers.push(CoreEvents.on(
AddonCalendarProvider.EDIT_EVENT_EVENT, ADDON_CALENDAR_EDIT_EVENT_EVENT,
(data) => { (data) => {
if (data && data.eventId) { if (data && data.eventId) {
this.manager?.getSource().markAllItemsUnloaded(); this.manager?.getSource().markAllItemsUnloaded();
@ -120,13 +130,13 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
)); ));
// Refresh data if calendar events are synchronized automatically. // Refresh data if calendar events are synchronized automatically.
this.eventObservers.push(CoreEvents.on(AddonCalendarSyncProvider.AUTO_SYNCED, () => { this.eventObservers.push(CoreEvents.on(ADDON_CALENDAR_AUTO_SYNCED, () => {
this.manager?.getSource().markAllItemsUnloaded(); this.manager?.getSource().markAllItemsUnloaded();
this.refreshData(false, true); this.refreshData(false, true);
}, this.currentSiteId)); }, this.currentSiteId));
// Refresh data if calendar events are synchronized manually but not by this page. // Refresh data if calendar events are synchronized manually but not by this page.
this.eventObservers.push(CoreEvents.on(AddonCalendarSyncProvider.MANUAL_SYNCED, (data) => { this.eventObservers.push(CoreEvents.on(ADDON_CALENDAR_MANUAL_SYNCED, (data) => {
const selectedDay = this.manager?.getSelectedItem(); const selectedDay = this.manager?.getSelectedItem();
if (data && (data.source != 'day' || !selectedDay || !data.moment || !selectedDay.moment.isSame(data.moment, 'day'))) { if (data && (data.source != 'day' || !selectedDay || !data.moment || !selectedDay.moment.isSame(data.moment, 'day'))) {
this.manager?.getSource().markAllItemsUnloaded(); this.manager?.getSource().markAllItemsUnloaded();
@ -136,7 +146,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
// Update the events when an event is deleted. // Update the events when an event is deleted.
this.eventObservers.push(CoreEvents.on( this.eventObservers.push(CoreEvents.on(
AddonCalendarProvider.DELETED_EVENT_EVENT, ADDON_CALENDAR_DELETED_EVENT_EVENT,
(data) => { (data) => {
if (data && !data.sent) { if (data && !data.sent) {
// Event was deleted in offline. Just mark it as deleted, no need to refresh. // Event was deleted in offline. Just mark it as deleted, no need to refresh.
@ -151,7 +161,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
// Listen for events "undeleted" (offline). // Listen for events "undeleted" (offline).
this.eventObservers.push(CoreEvents.on( this.eventObservers.push(CoreEvents.on(
AddonCalendarProvider.UNDELETED_EVENT_EVENT, ADDON_CALENDAR_UNDELETED_EVENT_EVENT,
(data) => { (data) => {
if (!data || !data.eventId) { if (!data || !data.eventId) {
return; return;
@ -164,7 +174,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
)); ));
this.eventObservers.push(CoreEvents.on( this.eventObservers.push(CoreEvents.on(
AddonCalendarProvider.FILTER_CHANGED_EVENT, ADDON_CALENDAR_FILTER_CHANGED_EVENT,
async (data) => { async (data) => {
this.filter = data; this.filter = data;
@ -212,7 +222,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
const types: string[] = []; const types: string[] = [];
CoreUtils.enumKeys(AddonCalendarEventType).forEach((name) => { CoreObject.enumKeys(AddonCalendarEventType).forEach((name) => {
const value = AddonCalendarEventType[name]; const value = AddonCalendarEventType[name];
this.filter[name] = CoreNavigator.getRouteBooleanParam(name) ?? true; this.filter[name] = CoreNavigator.getRouteBooleanParam(name) ?? true;
types.push(value); types.push(value);
@ -343,7 +353,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy {
result.moment = selectedDay?.moment; result.moment = selectedDay?.moment;
this.manager?.getSource().markAllItemsUnloaded(); this.manager?.getSource().markAllItemsUnloaded();
CoreEvents.trigger(AddonCalendarSyncProvider.MANUAL_SYNCED, result, this.currentSiteId); CoreEvents.trigger(ADDON_CALENDAR_MANUAL_SYNCED, result, this.currentSiteId);
} }
} catch (error) { } catch (error) {
if (showErrors) { if (showErrors) {
@ -597,7 +607,7 @@ class AddonCalendarDaySlidesItemsManagerSource extends CoreSwipeSlidesDynamicIte
const categories = await CoreCourses.getCategories(0, true); const categories = await CoreCourses.getCategories(0, true);
// Index categories by ID. // Index categories by ID.
this.categories = CoreUtils.arrayToObject(categories, 'id'); this.categories = CoreArray.toObject(categories, 'id');
} catch { } catch {
// Ignore errors. // Ignore errors.
} }

View File

@ -20,20 +20,18 @@ import { CoreSites } from '@services/sites';
import { CoreSync } from '@services/sync'; import { CoreSync } from '@services/sync';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { CoreCategoryData, CoreCourses, CoreCourseSearchedData, CoreEnrolledCourseData } from '@features/courses/services/courses'; import { CoreCategoryData, CoreCourses, CoreCourseSearchedData, CoreEnrolledCourseData } from '@features/courses/services/courses';
import { CoreEditorRichTextEditorComponent } from '@features/editor/components/rich-text-editor/rich-text-editor'; import { CoreEditorRichTextEditorComponent } from '@features/editor/components/rich-text-editor/rich-text-editor';
import { import {
AddonCalendarProvider,
AddonCalendarGetCalendarAccessInformationWSResponse, AddonCalendarGetCalendarAccessInformationWSResponse,
AddonCalendarEvent, AddonCalendarEvent,
AddonCalendarEventType,
AddonCalendar, AddonCalendar,
AddonCalendarSubmitCreateUpdateFormDataWSParams, AddonCalendarSubmitCreateUpdateFormDataWSParams,
} from '../../services/calendar'; } from '../../services/calendar';
import { AddonCalendarOffline } from '../../services/calendar-offline'; import { AddonCalendarOffline } from '../../services/calendar-offline';
import { AddonCalendarEventTypeOption, AddonCalendarHelper } from '../../services/calendar-helper'; import { AddonCalendarEventTypeOption, AddonCalendarHelper } from '../../services/calendar-helper';
import { AddonCalendarSync, AddonCalendarSyncProvider } from '../../services/calendar-sync'; import { AddonCalendarSync } from '../../services/calendar-sync';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreFilterHelper } from '@features/filter/services/filter-helper'; import { CoreFilterHelper } from '@features/filter/services/filter-helper';
@ -42,12 +40,20 @@ import { CoreError } from '@classes/errors/error';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CanLeave } from '@guards/can-leave'; import { CanLeave } from '@guards/can-leave';
import { CoreForms } from '@singletons/form'; import { CoreForms } from '@singletons/form';
import { CoreReminders, CoreRemindersService, CoreRemindersUnits } from '@features/reminders/services/reminders'; import { CoreReminders, CoreRemindersService } from '@features/reminders/services/reminders';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { ADDON_CALENDAR_COMPONENT } from '@addons/calendar/constants'; import {
ADDON_CALENDAR_COMPONENT,
ADDON_CALENDAR_EDIT_EVENT_EVENT,
ADDON_CALENDAR_NEW_EVENT_EVENT,
ADDON_CALENDAR_SYNC_ID,
AddonCalendarEventType,
} from '@addons/calendar/constants';
import { ContextLevel } from '@/core/constants'; import { ContextLevel } from '@/core/constants';
import { CorePopovers } from '@services/popovers'; import { CorePopovers } from '@services/popovers';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import { REMINDERS_DISABLED, CoreRemindersUnits } from '@features/reminders/constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Page that displays a form to create/edit an event. * Page that displays a form to create/edit an event.
@ -55,7 +61,7 @@ import { CoreLoadings } from '@services/loadings';
@Component({ @Component({
selector: 'page-addon-calendar-edit-event', selector: 'page-addon-calendar-edit-event',
templateUrl: 'edit-event.html', templateUrl: 'edit-event.html',
styleUrls: ['edit-event.scss'], styleUrl: 'edit-event.scss',
}) })
export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
@ -159,7 +165,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
try { try {
const [types, accessInfo] = await Promise.all([ const [types, accessInfo] = await Promise.all([
AddonCalendar.getAllowedEventTypes(this.courseId), AddonCalendar.getAllowedEventTypes(this.courseId),
CoreUtils.ignoreErrors(AddonCalendar.getAccessInformation(this.courseId), { CorePromiseUtils.ignoreErrors(AddonCalendar.getAccessInformation(this.courseId), {
canmanageentries: false, canmanageentries: false,
canmanageownentries: false, canmanageownentries: false,
canmanagegroupentries: false, canmanagegroupentries: false,
@ -179,7 +185,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
// Editing an event, get the event data. Wait for sync first. // Editing an event, get the event data. Wait for sync first.
const eventId = this.eventId; const eventId = this.eventId;
promises.push(AddonCalendarSync.waitForSync(AddonCalendarSyncProvider.SYNC_ID).then(async () => { promises.push(AddonCalendarSync.waitForSync(ADDON_CALENDAR_SYNC_ID).then(async () => {
// Do not block if the scope is already destroyed. // Do not block if the scope is already destroyed.
if (!this.isDestroyed && this.eventId) { if (!this.isDestroyed && this.eventId) {
CoreSync.blockOperation(ADDON_CALENDAR_COMPONENT, eventId); CoreSync.blockOperation(ADDON_CALENDAR_COMPONENT, eventId);
@ -363,7 +369,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
this.form.controls.repeateditall.setValue(1); this.form.controls.repeateditall.setValue(1);
} }
if (event.eventtype == AddonCalendarEventType.GROUP && courseId) { if (event.eventtype === AddonCalendarEventType.GROUP && courseId) {
await this.loadGroups(courseId); await this.loadGroups(courseId);
} }
} }
@ -489,12 +495,12 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
repeat: formData.repeat, repeat: formData.repeat,
}; };
if (formData.eventtype == AddonCalendarEventType.COURSE) { if (formData.eventtype === AddonCalendarEventType.COURSE) {
data.courseid = formData.courseid; data.courseid = formData.courseid;
} else if (formData.eventtype == AddonCalendarEventType.GROUP) { } else if (formData.eventtype === AddonCalendarEventType.GROUP) {
data.groupcourseid = formData.groupcourseid; data.groupcourseid = formData.groupcourseid;
data.groupid = formData.groupid; data.groupid = formData.groupid;
} else if (formData.eventtype == AddonCalendarEventType.CATEGORY) { } else if (formData.eventtype === AddonCalendarEventType.CATEGORY) {
data.categoryid = formData.categoryid; data.categoryid = formData.categoryid;
} }
@ -560,13 +566,13 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
if (this.eventId && this.eventId > 0) { if (this.eventId && this.eventId > 0) {
// Editing an event. // Editing an event.
CoreEvents.trigger( CoreEvents.trigger(
AddonCalendarProvider.EDIT_EVENT_EVENT, ADDON_CALENDAR_EDIT_EVENT_EVENT,
{ eventId: this.eventId }, { eventId: this.eventId },
this.currentSite.getId(), this.currentSite.getId(),
); );
} else { } else {
CoreEvents.trigger( CoreEvents.trigger(
AddonCalendarProvider.NEW_EVENT_EVENT, ADDON_CALENDAR_NEW_EVENT_EVENT,
{ {
eventId: event.id, eventId: event.id,
oldEventId: this.eventId, oldEventId: this.eventId,
@ -617,7 +623,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
// Check if default reminders are enabled. // Check if default reminders are enabled.
const defaultTime = await CoreReminders.getDefaultNotificationTime(this.currentSite.getId()); const defaultTime = await CoreReminders.getDefaultNotificationTime(this.currentSite.getId());
if (defaultTime === CoreRemindersService.DISABLED) { if (defaultTime === REMINDERS_DISABLED) {
return; return;
} }

View File

@ -17,11 +17,10 @@ import { AlertOptions } from '@ionic/core';
import { import {
AddonCalendar, AddonCalendar,
AddonCalendarEventToDisplay, AddonCalendarEventToDisplay,
AddonCalendarProvider,
} from '../../services/calendar'; } from '../../services/calendar';
import { AddonCalendarEventReminder, AddonCalendarHelper } from '../../services/calendar-helper'; import { AddonCalendarEventReminder, AddonCalendarHelper } from '../../services/calendar-helper';
import { AddonCalendarOffline } from '../../services/calendar-offline'; import { AddonCalendarOffline } from '../../services/calendar-offline';
import { AddonCalendarSync, AddonCalendarSyncEvents, AddonCalendarSyncProvider } from '../../services/calendar-sync'; import { AddonCalendarSync, AddonCalendarSyncEvents } from '../../services/calendar-sync';
import { CoreNetwork } from '@services/network'; import { CoreNetwork } from '@services/network';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
@ -32,13 +31,13 @@ import { CoreTimeUtils } from '@services/utils/time';
import { NgZone, Translate } from '@singletons'; import { NgZone, Translate } from '@singletons';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router'; import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker'; import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
import { AddonCalendarEventsSource } from '@addons/calendar/classes/events-source'; import { AddonCalendarEventsSource } from '@addons/calendar/classes/events-source';
import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager'; import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager';
import { CoreReminders, CoreRemindersService } from '@features/reminders/services/reminders'; import { CoreReminders } from '@features/reminders/services/reminders';
import { CoreLocalNotifications } from '@services/local-notifications'; import { CoreLocalNotifications } from '@services/local-notifications';
import { CorePlatform } from '@services/platform'; import { CorePlatform } from '@services/platform';
import { CoreConfig } from '@services/config'; import { CoreConfig } from '@services/config';
@ -46,6 +45,16 @@ import { CoreToasts, ToastDuration } from '@services/toasts';
import { CorePopovers } from '@services/popovers'; import { CorePopovers } from '@services/popovers';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import {
ADDON_CALENDAR_AUTO_SYNCED,
ADDON_CALENDAR_DELETED_EVENT_EVENT,
ADDON_CALENDAR_EDIT_EVENT_EVENT,
ADDON_CALENDAR_MANUAL_SYNCED,
ADDON_CALENDAR_NEW_EVENT_DISCARDED_EVENT,
ADDON_CALENDAR_NEW_EVENT_EVENT,
ADDON_CALENDAR_UNDELETED_EVENT_EVENT,
} from '@addons/calendar/constants';
import { REMINDERS_DEFAULT_NOTIFICATION_TIME_CHANGED } from '@features/reminders/constants';
/** /**
* Page that displays a single calendar event. * Page that displays a single calendar event.
@ -99,7 +108,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
this.canEdit = AddonCalendar.canEditEventsInSite(); this.canEdit = AddonCalendar.canEditEventsInSite();
// Listen for event edited. If current event is edited, reload the data. // Listen for event edited. If current event is edited, reload the data.
this.editEventObserver = CoreEvents.on(AddonCalendarProvider.EDIT_EVENT_EVENT, (data) => { this.editEventObserver = CoreEvents.on(ADDON_CALENDAR_EDIT_EVENT_EVENT, (data) => {
if (data && data.eventId === this.eventId) { if (data && data.eventId === this.eventId) {
this.eventLoaded = false; this.eventLoaded = false;
this.refreshEvent(true, false); this.refreshEvent(true, false);
@ -107,7 +116,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
}, this.currentSiteId); }, this.currentSiteId);
// Listen for event created. If user edits the data of a new offline event or it's sent to server, this event is triggered. // Listen for event created. If user edits the data of a new offline event or it's sent to server, this event is triggered.
this.newEventObserver = CoreEvents.on(AddonCalendarProvider.NEW_EVENT_EVENT, (data) => { this.newEventObserver = CoreEvents.on(ADDON_CALENDAR_NEW_EVENT_EVENT, (data) => {
if (this.eventId < 0 && data && (data.eventId === this.eventId || data.oldEventId === this.eventId)) { if (this.eventId < 0 && data && (data.eventId === this.eventId || data.oldEventId === this.eventId)) {
this.eventId = data.eventId; this.eventId = data.eventId;
this.eventLoaded = false; this.eventLoaded = false;
@ -117,14 +126,14 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
// Refresh data if this calendar event is synchronized automatically. // Refresh data if this calendar event is synchronized automatically.
this.syncObserver = CoreEvents.on( this.syncObserver = CoreEvents.on(
AddonCalendarSyncProvider.AUTO_SYNCED, ADDON_CALENDAR_AUTO_SYNCED,
(data) => this.checkSyncResult(false, data), (data) => this.checkSyncResult(false, data),
this.currentSiteId, this.currentSiteId,
); );
// Refresh data if calendar events are synchronized manually but not by this page. // Refresh data if calendar events are synchronized manually but not by this page.
this.manualSyncObserver = CoreEvents.on( this.manualSyncObserver = CoreEvents.on(
AddonCalendarSyncProvider.MANUAL_SYNCED, ADDON_CALENDAR_MANUAL_SYNCED,
(data) => this.checkSyncResult(true, data), (data) => this.checkSyncResult(true, data),
this.currentSiteId, this.currentSiteId,
); );
@ -138,7 +147,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
}); });
// Reload reminders if default notification time changes. // Reload reminders if default notification time changes.
this.defaultTimeChangedObserver = CoreEvents.on(CoreRemindersService.DEFAULT_NOTIFICATION_TIME_CHANGED, () => { this.defaultTimeChangedObserver = CoreEvents.on(REMINDERS_DEFAULT_NOTIFICATION_TIME_CHANGED, () => {
this.loadReminders(); this.loadReminders();
}, this.currentSiteId); }, this.currentSiteId);
@ -364,7 +373,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
result.source = 'event'; result.source = 'event';
CoreEvents.trigger( CoreEvents.trigger(
AddonCalendarSyncProvider.MANUAL_SYNCED, ADDON_CALENDAR_MANUAL_SYNCED,
result, result,
this.currentSiteId, this.currentSiteId,
); );
@ -471,7 +480,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
} }
promises.push(AddonCalendar.invalidateTimeFormat()); promises.push(AddonCalendar.invalidateTimeFormat());
await CoreUtils.allPromisesIgnoringErrors(promises); await CorePromiseUtils.allPromisesIgnoringErrors(promises);
await this.fetchEvent(sync, showErrors); await this.fetchEvent(sync, showErrors);
} }
@ -552,9 +561,9 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
// Trigger an event. // Trigger an event.
if (this.event.id < 0) { if (this.event.id < 0) {
CoreEvents.trigger(AddonCalendarProvider.NEW_EVENT_DISCARDED_EVENT, {}, CoreSites.getCurrentSiteId()); CoreEvents.trigger(ADDON_CALENDAR_NEW_EVENT_DISCARDED_EVENT, {}, CoreSites.getCurrentSiteId());
} else { } else {
CoreEvents.trigger(AddonCalendarProvider.DELETED_EVENT_EVENT, { CoreEvents.trigger(ADDON_CALENDAR_DELETED_EVENT_EVENT, {
eventId: this.eventId, eventId: this.eventId,
sent: onlineEventDeleted, sent: onlineEventDeleted,
}, CoreSites.getCurrentSiteId()); }, CoreSites.getCurrentSiteId());
@ -595,7 +604,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
await AddonCalendarOffline.unmarkDeleted(this.event.id); await AddonCalendarOffline.unmarkDeleted(this.event.id);
// Trigger an event. // Trigger an event.
CoreEvents.trigger(AddonCalendarProvider.UNDELETED_EVENT_EVENT, { CoreEvents.trigger(ADDON_CALENDAR_UNDELETED_EVENT_EVENT, {
eventId: this.eventId, eventId: this.eventId,
}, CoreSites.getCurrentSiteId()); }, CoreSites.getCurrentSiteId());

View File

@ -18,9 +18,9 @@ import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreCoursesHelper } from '@features/courses/services/courses-helper'; import { CoreCoursesHelper } from '@features/courses/services/courses-helper';
import { AddonCalendar, AddonCalendarProvider } from '../../services/calendar'; import { AddonCalendar } from '../../services/calendar';
import { AddonCalendarOffline } from '../../services/calendar-offline'; import { AddonCalendarOffline } from '../../services/calendar-offline';
import { AddonCalendarSync, AddonCalendarSyncProvider } from '../../services/calendar-sync'; import { AddonCalendarSync } from '../../services/calendar-sync';
import { AddonCalendarFilter, AddonCalendarHelper } from '../../services/calendar-helper'; import { AddonCalendarFilter, AddonCalendarHelper } from '../../services/calendar-helper';
import { NgZone } from '@singletons'; import { NgZone } from '@singletons';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
@ -31,6 +31,16 @@ import { AddonCalendarUpcomingEventsComponent } from '../../components/upcoming-
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreModals } from '@services/modals'; import { CoreModals } from '@services/modals';
import {
ADDON_CALENDAR_AUTO_SYNCED,
ADDON_CALENDAR_DELETED_EVENT_EVENT,
ADDON_CALENDAR_EDIT_EVENT_EVENT,
ADDON_CALENDAR_FILTER_CHANGED_EVENT,
ADDON_CALENDAR_MANUAL_SYNCED,
ADDON_CALENDAR_NEW_EVENT_DISCARDED_EVENT,
ADDON_CALENDAR_NEW_EVENT_EVENT,
ADDON_CALENDAR_UNDELETED_EVENT_EVENT,
} from '@addons/calendar/constants';
/** /**
* Page that displays the calendar events. * Page that displays the calendar events.
@ -85,7 +95,7 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy {
// Listen for events added. When an event is added, reload the data. // Listen for events added. When an event is added, reload the data.
this.newEventObserver = CoreEvents.on( this.newEventObserver = CoreEvents.on(
AddonCalendarProvider.NEW_EVENT_EVENT, ADDON_CALENDAR_NEW_EVENT_EVENT,
(data) => { (data) => {
if (data && data.eventId) { if (data && data.eventId) {
this.loaded = false; this.loaded = false;
@ -96,14 +106,14 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy {
); );
// Listen for new event discarded event. When it does, reload the data. // Listen for new event discarded event. When it does, reload the data.
this.discardedObserver = CoreEvents.on(AddonCalendarProvider.NEW_EVENT_DISCARDED_EVENT, () => { this.discardedObserver = CoreEvents.on(ADDON_CALENDAR_NEW_EVENT_DISCARDED_EVENT, () => {
this.loaded = false; this.loaded = false;
this.refreshData(true, false, true); this.refreshData(true, false, true);
}, this.currentSiteId); }, this.currentSiteId);
// Listen for events edited. When an event is edited, reload the data. // Listen for events edited. When an event is edited, reload the data.
this.editEventObserver = CoreEvents.on( this.editEventObserver = CoreEvents.on(
AddonCalendarProvider.EDIT_EVENT_EVENT, ADDON_CALENDAR_EDIT_EVENT_EVENT,
(data) => { (data) => {
if (data && data.eventId) { if (data && data.eventId) {
this.loaded = false; this.loaded = false;
@ -114,13 +124,13 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy {
); );
// Refresh data if calendar events are synchronized automatically. // Refresh data if calendar events are synchronized automatically.
this.syncObserver = CoreEvents.on(AddonCalendarSyncProvider.AUTO_SYNCED, () => { this.syncObserver = CoreEvents.on(ADDON_CALENDAR_AUTO_SYNCED, () => {
this.loaded = false; this.loaded = false;
this.refreshData(false, false, true); this.refreshData(false, false, true);
}, this.currentSiteId); }, this.currentSiteId);
// Refresh data if calendar events are synchronized manually but not by this page. // Refresh data if calendar events are synchronized manually but not by this page.
this.manualSyncObserver = CoreEvents.on(AddonCalendarSyncProvider.MANUAL_SYNCED, (data) => { this.manualSyncObserver = CoreEvents.on(ADDON_CALENDAR_MANUAL_SYNCED, (data) => {
if (data && data.source != 'index') { if (data && data.source != 'index') {
this.loaded = false; this.loaded = false;
this.refreshData(false, false, true); this.refreshData(false, false, true);
@ -128,18 +138,18 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy {
}, this.currentSiteId); }, this.currentSiteId);
// Update the events when an event is deleted. // Update the events when an event is deleted.
this.deleteEventObserver = CoreEvents.on(AddonCalendarProvider.DELETED_EVENT_EVENT, () => { this.deleteEventObserver = CoreEvents.on(ADDON_CALENDAR_DELETED_EVENT_EVENT, () => {
this.loaded = false; this.loaded = false;
this.refreshData(false, false, true); this.refreshData(false, false, true);
}, this.currentSiteId); }, this.currentSiteId);
// Update the "hasOffline" property if an event deleted in offline is restored. // Update the "hasOffline" property if an event deleted in offline is restored.
this.undeleteEventObserver = CoreEvents.on(AddonCalendarProvider.UNDELETED_EVENT_EVENT, async () => { this.undeleteEventObserver = CoreEvents.on(ADDON_CALENDAR_UNDELETED_EVENT_EVENT, async () => {
this.hasOffline = await AddonCalendarOffline.hasOfflineData(); this.hasOffline = await AddonCalendarOffline.hasOfflineData();
}, this.currentSiteId); }, this.currentSiteId);
this.filterChangedObserver = CoreEvents.on( this.filterChangedObserver = CoreEvents.on(
AddonCalendarProvider.FILTER_CHANGED_EVENT, ADDON_CALENDAR_FILTER_CHANGED_EVENT,
async (filterData) => { async (filterData) => {
this.filter = filterData; this.filter = filterData;
@ -205,7 +215,7 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy {
result.source = 'index'; result.source = 'index';
CoreEvents.trigger( CoreEvents.trigger(
AddonCalendarSyncProvider.MANUAL_SYNCED, ADDON_CALENDAR_MANUAL_SYNCED,
result, result,
this.currentSiteId, this.currentSiteId,
); );

View File

@ -18,6 +18,7 @@ import {
CoreReminders, CoreReminders,
CoreRemindersService, CoreRemindersService,
} from '@features/reminders/services/reminders'; } from '@features/reminders/services/reminders';
import { REMINDERS_DISABLED } from '@features/reminders/constants';
/** /**
* Page that displays the calendar settings. * Page that displays the calendar settings.
@ -67,7 +68,7 @@ export class AddonCalendarSettingsPage implements OnInit {
return; return;
} }
await CoreReminders.setDefaultNotificationTime(reminderTime.timeBefore ?? CoreRemindersService.DISABLED); await CoreReminders.setDefaultNotificationTime(reminderTime.timeBefore ?? REMINDERS_DISABLED);
this.updateDefaultTimeLabel(); this.updateDefaultTimeLabel();
} }

View File

@ -20,36 +20,30 @@ import {
AddonCalendarEvent, AddonCalendarEvent,
AddonCalendarEventBase, AddonCalendarEventBase,
AddonCalendarEventToDisplay, AddonCalendarEventToDisplay,
AddonCalendarEventType,
AddonCalendarGetEventsEvent, AddonCalendarGetEventsEvent,
AddonCalendarProvider,
AddonCalendarWeek, AddonCalendarWeek,
AddonCalendarWeekDay, AddonCalendarWeekDay,
} from './calendar'; } from './calendar';
import { CoreConfig } from '@services/config'; import { CoreConfig } from '@services/config';
import { CoreUtils } from '@services/utils/utils'; import { CoreObject } from '@singletons/object';
import { CoreCourse } from '@features/course/services/course'; import { CoreCourse } from '@features/course/services/course';
import { ContextLevel, CoreConstants } from '@/core/constants'; import { ContextLevel, CoreConstants } from '@/core/constants';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonCalendarSyncInvalidateEvent } from './calendar-sync';
import { AddonCalendarOfflineEventDBRecord } from './database/calendar-offline'; import { AddonCalendarOfflineEventDBRecord } from './database/calendar-offline';
import { CoreCategoryData } from '@features/courses/services/courses'; import { CoreCategoryData } from '@features/courses/services/courses';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreReminders, CoreRemindersService } from '@features/reminders/services/reminders'; import { CoreReminders, CoreRemindersService } from '@features/reminders/services/reminders';
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
import { ADDON_CALENDAR_COMPONENT } from '../constants'; import {
ADDON_CALENDAR_COMPONENT,
/** ADDON_CALENDAR_STARTING_WEEK_DAY,
* Context levels enumeration. AddonCalendarEventIcons,
*/ AddonCalendarEventType,
export enum AddonCalendarEventIcons { } from '../constants';
SITE = 'fas-globe', import { AddonCalendarSyncInvalidateEvent } from './calendar-sync';
CATEGORY = 'fas-cubes', import { REMINDERS_DISABLED, REMINDERS_DEFAULT_REMINDER_TIMEBEFORE } from '@features/reminders/constants';
COURSE = 'fas-graduation-cap', import { CorePromiseUtils } from '@singletons/promise-utils';
GROUP = 'fas-users',
USER = 'fas-user',
}
/** /**
* Service that provides some features regarding lists of courses and categories. * Service that provides some features regarding lists of courses and categories.
@ -67,7 +61,7 @@ export class AddonCalendarHelperProvider {
*/ */
getEventIcon(eventType: AddonCalendarEventType | string): string { getEventIcon(eventType: AddonCalendarEventType | string): string {
if (this.eventTypeIcons.length == 0) { if (this.eventTypeIcons.length == 0) {
CoreUtils.enumKeys(AddonCalendarEventType).forEach((name) => { CoreObject.enumKeys(AddonCalendarEventType).forEach((name) => {
const value = AddonCalendarEventType[name]; const value = AddonCalendarEventType[name];
this.eventTypeIcons[value] = AddonCalendarEventIcons[name]; this.eventTypeIcons[value] = AddonCalendarEventIcons[name];
}); });
@ -322,7 +316,7 @@ export class AddonCalendarHelperProvider {
const defaultTime = await CoreReminders.getDefaultNotificationTime(siteId); const defaultTime = await CoreReminders.getDefaultNotificationTime(siteId);
let defaultLabel: string | undefined; let defaultLabel: string | undefined;
if (defaultTime > CoreRemindersService.DISABLED) { if (defaultTime > REMINDERS_DISABLED) {
const data = CoreRemindersService.convertSecondsToValueAndUnit(defaultTime); const data = CoreRemindersService.convertSecondsToValueAndUnit(defaultTime);
defaultLabel = CoreReminders.getUnitValueLabel(data.value, data.unit, true); defaultLabel = CoreReminders.getUnitValueLabel(data.value, data.unit, true);
} }
@ -332,7 +326,7 @@ export class AddonCalendarHelperProvider {
id: reminder.id, id: reminder.id,
}; };
if (reminder.timebefore === CoreRemindersService.DEFAULT_REMINDER_TIMEBEFORE) { if (reminder.timebefore === REMINDERS_DEFAULT_REMINDER_TIMEBEFORE) {
// Default time. Check if default notifications are disabled. // Default time. Check if default notifications are disabled.
if (defaultLabel !== undefined) { if (defaultLabel !== undefined) {
formatted.label = defaultLabel; formatted.label = defaultLabel;
@ -418,7 +412,7 @@ export class AddonCalendarHelperProvider {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
// Get starting week day user preference, fallback to site configuration. // Get starting week day user preference, fallback to site configuration.
let startWeekDayStr = site.getStoredConfig('calendar_startwday') || '1'; let startWeekDayStr = site.getStoredConfig('calendar_startwday') || '1';
startWeekDayStr = await CoreConfig.get(AddonCalendarProvider.STARTING_WEEK_DAY, startWeekDayStr); startWeekDayStr = await CoreConfig.get(ADDON_CALENDAR_STARTING_WEEK_DAY, startWeekDayStr);
const startWeekDay = parseInt(startWeekDayStr, 10); const startWeekDay = parseInt(startWeekDayStr, 10);
const today = moment(); const today = moment();
@ -645,7 +639,7 @@ export class AddonCalendarHelperProvider {
const repeatedEvents = const repeatedEvents =
await AddonCalendar.getLocalEventsByRepeatIdFromLocalDb(eventData.repeatid, site.id); await AddonCalendar.getLocalEventsByRepeatIdFromLocalDb(eventData.repeatid, site.id);
await CoreUtils.allPromises(repeatedEvents.map((event) => await CorePromiseUtils.allPromises(repeatedEvents.map((event) =>
AddonCalendar.invalidateEvent(event.id))); AddonCalendar.invalidateEvent(event.id)));
return; return;
@ -666,7 +660,7 @@ export class AddonCalendarHelperProvider {
})); }));
try { try {
await CoreUtils.allPromisesIgnoringErrors(promises); await CorePromiseUtils.allPromisesIgnoringErrors(promises);
} finally { } finally {
const treatedMonths = {}; const treatedMonths = {};
const treatedDays = {}; const treatedDays = {};
@ -734,7 +728,7 @@ export class AddonCalendarHelperProvider {
} }
}); });
await CoreUtils.allPromisesIgnoringErrors(finalPromises); await CorePromiseUtils.allPromisesIgnoringErrors(finalPromises);
} }
} }
@ -784,7 +778,6 @@ export class AddonCalendarHelperProvider {
} }
} }
export const AddonCalendarHelper = makeSingleton(AddonCalendarHelperProvider); export const AddonCalendarHelper = makeSingleton(AddonCalendarHelperProvider);
/** /**

View File

@ -15,7 +15,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { SQLiteDBRecordValues } from '@classes/sqlitedb'; import { SQLiteDBRecordValues } from '@classes/sqlitedb';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CoreArray } from '@singletons/array';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonCalendarSubmitCreateUpdateFormDataWSParams } from './calendar'; import { AddonCalendarSubmitCreateUpdateFormDataWSParams } from './calendar';
import { import {
@ -62,7 +62,7 @@ export class AddonCalendarOfflineProvider {
const result = await Promise.all(promises); const result = await Promise.all(promises);
return CoreUtils.mergeArraysWithoutDuplicates(result[0], result[1]); return CoreArray.mergeWithoutDuplicates(result[0], result[1]);
} }
/** /**

View File

@ -17,7 +17,7 @@ import { CoreSyncBaseProvider, CoreSyncBlockedError } from '@classes/base-sync';
import { CoreNetwork } from '@services/network'; import { CoreNetwork } from '@services/network';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { import {
AddonCalendar, AddonCalendar,
AddonCalendarEvent, AddonCalendarEvent,
@ -29,7 +29,14 @@ import { makeSingleton, Translate } from '@singletons';
import { CoreSync, CoreSyncResult } from '@services/sync'; import { CoreSync, CoreSyncResult } from '@services/sync';
import { CoreNetworkError } from '@classes/errors/network-error'; import { CoreNetworkError } from '@classes/errors/network-error';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { ADDON_CALENDAR_COMPONENT } from '../constants'; import {
ADDON_CALENDAR_AUTO_SYNCED,
ADDON_CALENDAR_COMPONENT,
ADDON_CALENDAR_MANUAL_SYNCED,
ADDON_CALENDAR_SYNC_ID,
} from '../constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreWSError } from '@classes/errors/wserror';
/** /**
* Service to sync calendar. * Service to sync calendar.
@ -37,10 +44,6 @@ import { ADDON_CALENDAR_COMPONENT } from '../constants';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalendarSyncEvents> { export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalendarSyncEvents> {
static readonly AUTO_SYNCED = 'addon_calendar_autom_synced';
static readonly MANUAL_SYNCED = 'addon_calendar_manual_synced';
static readonly SYNC_ID = 'calendar';
protected componentTranslatableString = 'addon.calendar.calendarevent'; protected componentTranslatableString = 'addon.calendar.calendarevent';
constructor() { constructor() {
@ -72,7 +75,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
if (result?.updated) { if (result?.updated) {
// Sync successful, send event. // Sync successful, send event.
CoreEvents.trigger(AddonCalendarSyncProvider.AUTO_SYNCED, result, siteId); CoreEvents.trigger(ADDON_CALENDAR_AUTO_SYNCED, result, siteId);
} }
} }
@ -85,7 +88,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
async syncEventsIfNeeded(siteId?: string): Promise<AddonCalendarSyncEvents | undefined> { async syncEventsIfNeeded(siteId?: string): Promise<AddonCalendarSyncEvents | undefined> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const needed = await this.isSyncNeeded(AddonCalendarSyncProvider.SYNC_ID, siteId); const needed = await this.isSyncNeeded(ADDON_CALENDAR_SYNC_ID, siteId);
if (needed) { if (needed) {
return this.syncEvents(siteId); return this.syncEvents(siteId);
@ -101,7 +104,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
async syncEvents(siteId?: string): Promise<AddonCalendarSyncEvents> { async syncEvents(siteId?: string): Promise<AddonCalendarSyncEvents> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
const currentSyncPromise = this.getOngoingSync(AddonCalendarSyncProvider.SYNC_ID, siteId); const currentSyncPromise = this.getOngoingSync(ADDON_CALENDAR_SYNC_ID, siteId);
if (currentSyncPromise) { if (currentSyncPromise) {
// There's already a sync ongoing for this site, return the promise. // There's already a sync ongoing for this site, return the promise.
return currentSyncPromise; return currentSyncPromise;
@ -112,7 +115,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
// Get offline events. // Get offline events.
const syncPromise = this.performSyncEvents(siteId); const syncPromise = this.performSyncEvents(siteId);
return this.addOngoingSync(AddonCalendarSyncProvider.SYNC_ID, syncPromise, siteId); return this.addOngoingSync(ADDON_CALENDAR_SYNC_ID, syncPromise, siteId);
} }
/** /**
@ -131,7 +134,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
updated: false, updated: false,
}; };
const eventIds: number[] = await CoreUtils.ignoreErrors(AddonCalendarOffline.getAllEventsIds(siteId), []); const eventIds: number[] = await CorePromiseUtils.ignoreErrors(AddonCalendarOffline.getAllEventsIds(siteId), []);
if (eventIds.length > 0) { if (eventIds.length > 0) {
if (!CoreNetwork.isOnline()) { if (!CoreNetwork.isOnline()) {
@ -141,7 +144,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
const promises = eventIds.map((eventId) => this.syncOfflineEvent(eventId, result, siteId)); const promises = eventIds.map((eventId) => this.syncOfflineEvent(eventId, result, siteId));
await CoreUtils.allPromises(promises); await CorePromiseUtils.allPromises(promises);
if (result.updated) { if (result.updated) {
@ -151,12 +154,12 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
AddonCalendarHelper.refreshAfterChangeEvents(result.toinvalidate, siteId), AddonCalendarHelper.refreshAfterChangeEvents(result.toinvalidate, siteId),
]; ];
await CoreUtils.ignoreErrors(Promise.all(promises)); await CorePromiseUtils.ignoreErrors(Promise.all(promises));
} }
} }
// Sync finished, set sync time. // Sync finished, set sync time.
await CoreUtils.ignoreErrors(this.setSyncTime(AddonCalendarSyncProvider.SYNC_ID, siteId)); await CorePromiseUtils.ignoreErrors(this.setSyncTime(ADDON_CALENDAR_SYNC_ID, siteId));
// All done, return the result. // All done, return the result.
return result; return result;
@ -217,7 +220,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
await Promise.all(promises); await Promise.all(promises);
} catch (error) { } catch (error) {
if (!CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
// Local error, reject. // Local error, reject.
throw error; throw error;
} }
@ -282,7 +285,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
return AddonCalendarOffline.deleteEvent(event.id, siteId); return AddonCalendarOffline.deleteEvent(event.id, siteId);
} catch (error) { } catch (error) {
if (!CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
// Local error, reject. // Local error, reject.
throw error; throw error;
} }
@ -298,7 +301,6 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
} }
} }
export const AddonCalendarSync = makeSingleton(AddonCalendarSyncProvider); export const AddonCalendarSync = makeSingleton(AddonCalendarSyncProvider);
export type AddonCalendarSyncEvents = CoreSyncResult & { export type AddonCalendarSyncEvents = CoreSyncResult & {
@ -316,3 +318,17 @@ export type AddonCalendarSyncInvalidateEvent = {
timestart: number; timestart: number;
repeated: number; repeated: number;
}; };
declare module '@singletons/events' {
/**
* Augment CoreEventsData interface with events specific to this service.
*
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
*/
export interface CoreEventsData {
[ADDON_CALENDAR_MANUAL_SYNCED]: AddonCalendarSyncEvents;
[ADDON_CALENDAR_AUTO_SYNCED]: AddonCalendarSyncEvents;
}
}

View File

@ -19,7 +19,7 @@ import { CoreNetwork } from '@services/network';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils'; import { CoreObject } from '@singletons/object';
import { CoreGroups } from '@services/groups'; import { CoreGroups } from '@services/groups';
import { CoreLocalNotifications } from '@services/local-notifications'; import { CoreLocalNotifications } from '@services/local-notifications';
import { CoreConfig } from '@services/config'; import { CoreConfig } from '@services/config';
@ -27,41 +27,41 @@ import { AddonCalendarOffline } from './calendar-offline';
import { CoreUser } from '@features/user/services/user'; import { CoreUser } from '@features/user/services/user';
import { CoreWSExternalWarning, CoreWSDate } from '@services/ws'; import { CoreWSExternalWarning, CoreWSDate } from '@services/ws';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { AddonCalendarEventDBRecord, EVENTS_TABLE } from './database/calendar'; import { AddonCalendarEventDBRecord } from './database/calendar';
import { CoreCourses } from '@features/courses/services/courses'; import { CoreCourses } from '@features/courses/services/courses';
import { ContextLevel, CoreConstants } from '@/core/constants'; import { ContextLevel, CoreCacheUpdateFrequency, CoreConstants } from '@/core/constants';
import { CoreWSError } from '@classes/errors/wserror'; import { CoreWSError } from '@classes/errors/wserror';
import { ApplicationInit, makeSingleton, Translate } from '@singletons'; import { ApplicationInit, makeSingleton, Translate } from '@singletons';
import { AddonCalendarOfflineEventDBRecord } from './database/calendar-offline'; import { AddonCalendarOfflineEventDBRecord } from './database/calendar-offline';
import { AddonCalendarMainMenuHandlerService } from './handlers/mainmenu';
import { SafeUrl } from '@angular/platform-browser'; import { SafeUrl } from '@angular/platform-browser';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { AddonCalendarFilter } from './calendar-helper';
import { AddonCalendarSyncEvents, AddonCalendarSyncProvider } from './calendar-sync';
import { CorePath } from '@singletons/path'; import { CorePath } from '@singletons/path';
import { CorePlatform } from '@services/platform'; import { CorePlatform } from '@services/platform';
import { import {
CoreReminderData, CoreReminderData,
CoreReminders, CoreReminders,
CoreRemindersPushNotificationData, CoreRemindersPushNotificationData,
CoreRemindersService,
} from '@features/reminders/services/reminders'; } from '@features/reminders/services/reminders';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { ADDON_CALENDAR_COMPONENT } from '../constants'; import {
ADDON_CALENDAR_COMPONENT,
const ROOT_CACHE_KEY = 'mmaCalendar:'; ADDON_CALENDAR_DAYS_INTERVAL,
ADDON_CALENDAR_DELETED_EVENT_EVENT,
/** ADDON_CALENDAR_EDIT_EVENT_EVENT,
* Main calendar Event types enumeration. ADDON_CALENDAR_EVENTS_TABLE,
*/ ADDON_CALENDAR_FILTER_CHANGED_EVENT,
export enum AddonCalendarEventType { ADDON_CALENDAR_NEW_EVENT_EVENT,
SITE = 'site', ADDON_CALENDAR_PAGE_NAME,
CATEGORY = 'category', ADDON_CALENDAR_STARTING_WEEK_DAY,
COURSE = 'course', ADDON_CALENDAR_TF_12,
GROUP = 'group', ADDON_CALENDAR_TF_24,
USER = 'user', ADDON_CALENDAR_UNDELETED_EVENT_EVENT,
} AddonCalendarEventType,
} from '../constants';
import { REMINDERS_DEFAULT_REMINDER_TIMEBEFORE } from '@features/reminders/constants';
import { AddonCalendarFilter } from './calendar-helper';
import { CorePromiseUtils } from '@singletons/promise-utils';
declare module '@singletons/events' { declare module '@singletons/events' {
@ -71,13 +71,11 @@ declare module '@singletons/events' {
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation * @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
*/ */
export interface CoreEventsData { export interface CoreEventsData {
[AddonCalendarProvider.NEW_EVENT_EVENT]: AddonCalendarUpdatedEventEvent; [ADDON_CALENDAR_NEW_EVENT_EVENT]: AddonCalendarUpdatedEvent;
[AddonCalendarProvider.EDIT_EVENT_EVENT]: AddonCalendarUpdatedEventEvent; [ADDON_CALENDAR_EDIT_EVENT_EVENT]: AddonCalendarUpdatedEvent;
[AddonCalendarProvider.DELETED_EVENT_EVENT]: AddonCalendarUpdatedEventEvent; [ADDON_CALENDAR_DELETED_EVENT_EVENT]: AddonCalendarUpdatedEvent;
[AddonCalendarProvider.UNDELETED_EVENT_EVENT]: AddonCalendarUpdatedEventEvent; [ADDON_CALENDAR_UNDELETED_EVENT_EVENT]: AddonCalendarUpdatedEvent;
[AddonCalendarProvider.FILTER_CHANGED_EVENT]: AddonCalendarFilter; [ADDON_CALENDAR_FILTER_CHANGED_EVENT]: AddonCalendarFilter;
[AddonCalendarSyncProvider.MANUAL_SYNCED]: AddonCalendarSyncEvents;
[AddonCalendarSyncProvider.AUTO_SYNCED]: AddonCalendarSyncEvents;
} }
} }
@ -88,20 +86,7 @@ declare module '@singletons/events' {
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonCalendarProvider { export class AddonCalendarProvider {
static readonly DAYS_INTERVAL = 30; protected static weekDays: AddonCalendarWeekDaysTranslationKeys[] = [
static readonly STARTING_WEEK_DAY = 'addon_calendar_starting_week_day';
static readonly NEW_EVENT_EVENT = 'addon_calendar_new_event';
static readonly NEW_EVENT_DISCARDED_EVENT = 'addon_calendar_new_event_discarded';
static readonly EDIT_EVENT_EVENT = 'addon_calendar_edit_event';
static readonly DELETED_EVENT_EVENT = 'addon_calendar_deleted_event';
static readonly UNDELETED_EVENT_EVENT = 'addon_calendar_undeleted_event';
static readonly FILTER_CHANGED_EVENT = 'addon_calendar_filter_changed_event';
static readonly CALENDAR_TF_24 = '%H:%M'; // Calendar time in 24 hours format.
static readonly CALENDAR_TF_12 = '%I:%M %p'; // Calendar time in 12 hours format.
protected weekDays: AddonCalendarWeekDaysTranslationKeys[] = [
{ {
shortname: 'addon.calendar.sun', shortname: 'addon.calendar.sun',
fullname: 'addon.calendar.sunday', fullname: 'addon.calendar.sunday',
@ -132,6 +117,8 @@ export class AddonCalendarProvider {
}, },
]; ];
protected static readonly ROOT_CACHE_KEY = 'mmaCalendar:';
/** /**
* Check if a certain site allows creating and editing events. * Check if a certain site allows creating and editing events.
* *
@ -199,7 +186,7 @@ export class AddonCalendarProvider {
return true; return true;
} catch (error) { } catch (error) {
if (error && !CoreUtils.isWebServiceError(error)) { if (error && !CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return storeOffline(); return storeOffline();
} else { } else {
@ -248,7 +235,7 @@ export class AddonCalendarProvider {
const promises: Promise<unknown>[] = []; const promises: Promise<unknown>[] = [];
promises.push(site.getDb().deleteRecords( promises.push(site.getDb().deleteRecords(
EVENTS_TABLE, ADDON_CALENDAR_EVENTS_TABLE,
{ id: eventId }, { id: eventId },
)); ));
promises.push(CoreReminders.removeReminders({ promises.push(CoreReminders.removeReminders({
@ -256,7 +243,7 @@ export class AddonCalendarProvider {
component: ADDON_CALENDAR_COMPONENT, component: ADDON_CALENDAR_COMPONENT,
} , siteId)); } , siteId));
await CoreUtils.ignoreErrors(Promise.all(promises)); await CorePromiseUtils.ignoreErrors(Promise.all(promises));
} }
/** /**
@ -297,7 +284,7 @@ export class AddonCalendarProvider {
} }
CoreNavigator.navigateToSitePath( CoreNavigator.navigateToSitePath(
AddonCalendarMainMenuHandlerService.PAGE_NAME, ADDON_CALENDAR_PAGE_NAME,
{ {
siteId: notification.siteId, siteId: notification.siteId,
preferCurrentTab: false, preferCurrentTab: false,
@ -429,7 +416,7 @@ export class AddonCalendarProvider {
* @returns Cache key. * @returns Cache key.
*/ */
protected getAccessInformationCacheKey(courseId?: number): string { protected getAccessInformationCacheKey(courseId?: number): string {
return ROOT_CACHE_KEY + 'accessInformation:' + (courseId || 0); return AddonCalendarProvider.ROOT_CACHE_KEY + 'accessInformation:' + (courseId || 0);
} }
/** /**
@ -441,7 +428,7 @@ export class AddonCalendarProvider {
async getAllEventsFromLocalDb(siteId?: string): Promise<AddonCalendarEventDBRecord[]> { async getAllEventsFromLocalDb(siteId?: string): Promise<AddonCalendarEventDBRecord[]> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
return site.getDb().getAllRecords(EVENTS_TABLE); return site.getDb().getAllRecords(ADDON_CALENDAR_EVENTS_TABLE);
} }
/** /**
@ -482,7 +469,7 @@ export class AddonCalendarProvider {
* @returns Cache key. * @returns Cache key.
*/ */
protected getAllowedEventTypesCacheKey(courseId?: number): string { protected getAllowedEventTypesCacheKey(courseId?: number): string {
return ROOT_CACHE_KEY + 'allowedEventTypes:' + (courseId || 0); return AddonCalendarProvider.ROOT_CACHE_KEY + 'allowedEventTypes:' + (courseId || 0);
} }
/** /**
@ -527,9 +514,9 @@ export class AddonCalendarProvider {
format = site.getStoredConfig('calendar_site_timeformat'); format = site.getStoredConfig('calendar_site_timeformat');
} }
if (format === AddonCalendarProvider.CALENDAR_TF_12) { if (format === ADDON_CALENDAR_TF_12) {
format = Translate.instant('core.strftimetime12'); format = Translate.instant('core.strftimetime12');
} else if (format === AddonCalendarProvider.CALENDAR_TF_24) { } else if (format === ADDON_CALENDAR_TF_24) {
format = Translate.instant('core.strftimetime24'); format = Translate.instant('core.strftimetime24');
} }
@ -577,7 +564,7 @@ export class AddonCalendarProvider {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getEventCacheKey(id), cacheKey: this.getEventCacheKey(id),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
const params: AddonCalendarGetCalendarEventsWSParams = { const params: AddonCalendarGetCalendarEventsWSParams = {
options: { options: {
@ -613,7 +600,7 @@ export class AddonCalendarProvider {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getEventCacheKey(id), cacheKey: this.getEventCacheKey(id),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
const params: AddonCalendarGetCalendarEventByIdWSParams = { const params: AddonCalendarGetCalendarEventByIdWSParams = {
eventid: id, eventid: id,
@ -641,7 +628,7 @@ export class AddonCalendarProvider {
* @returns Cache key. * @returns Cache key.
*/ */
protected getEventCacheKey(id: number): string { protected getEventCacheKey(id: number): string {
return ROOT_CACHE_KEY + 'events:' + id; return AddonCalendarProvider.ROOT_CACHE_KEY + 'events:' + id;
} }
/** /**
@ -654,7 +641,7 @@ export class AddonCalendarProvider {
async getEventFromLocalDb(id: number, siteId?: string): Promise<AddonCalendarGetEventsEvent | AddonCalendarEvent> { async getEventFromLocalDb(id: number, siteId?: string): Promise<AddonCalendarGetEventsEvent | AddonCalendarEvent> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
const record: AddonCalendarGetEventsEvent | AddonCalendarEvent | AddonCalendarEventDBRecord = const record: AddonCalendarGetEventsEvent | AddonCalendarEvent | AddonCalendarEventDBRecord =
await site.getDb().getRecord(EVENTS_TABLE, { id: id }); await site.getDb().getRecord(ADDON_CALENDAR_EVENTS_TABLE, { id: id });
const eventConverted = record as AddonCalendarEvent; const eventConverted = record as AddonCalendarEvent;
const originalEvent = record as AddonCalendarGetEventsEvent; const originalEvent = record as AddonCalendarGetEventsEvent;
@ -662,8 +649,8 @@ export class AddonCalendarProvider {
// Calculate data to match the new WS. // Calculate data to match the new WS.
eventConverted.descriptionformat = originalEvent.format; eventConverted.descriptionformat = originalEvent.format;
eventConverted.iscourseevent = originalEvent.eventtype == AddonCalendarEventType.COURSE; eventConverted.iscourseevent = originalEvent.eventtype === AddonCalendarEventType.COURSE;
eventConverted.iscategoryevent = originalEvent.eventtype == AddonCalendarEventType.CATEGORY; eventConverted.iscategoryevent = originalEvent.eventtype === AddonCalendarEventType.CATEGORY;
eventConverted.normalisedeventtype = this.getEventType(recordAsRecord); eventConverted.normalisedeventtype = this.getEventType(recordAsRecord);
try { try {
eventConverted.category = CoreText.parseJSON(recordAsRecord.category || ''); eventConverted.category = CoreText.parseJSON(recordAsRecord.category || '');
@ -699,7 +686,7 @@ export class AddonCalendarProvider {
siteId?: string, siteId?: string,
): Promise<void> { ): Promise<void> {
timebefore = timebefore ?? CoreRemindersService.DEFAULT_REMINDER_TIMEBEFORE; timebefore = timebefore ?? REMINDERS_DEFAULT_REMINDER_TIMEBEFORE;
const previousReminders = await CoreReminders.getReminders({ const previousReminders = await CoreReminders.getReminders({
instanceId: event.id, instanceId: event.id,
@ -779,7 +766,7 @@ export class AddonCalendarProvider {
} }
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getDayEventsCacheKey(year, month, day, courseId, categoryId), cacheKey: this.getDayEventsCacheKey(year, month, day, courseId, categoryId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
if (ignoreCache) { if (ignoreCache) {
preSets.getFromCache = false; preSets.getFromCache = false;
@ -797,7 +784,7 @@ export class AddonCalendarProvider {
* @returns Prefix Cache key. * @returns Prefix Cache key.
*/ */
protected getDayEventsPrefixCacheKey(): string { protected getDayEventsPrefixCacheKey(): string {
return ROOT_CACHE_KEY + 'day:'; return AddonCalendarProvider.ROOT_CACHE_KEY + 'day:';
} }
/** /**
@ -843,7 +830,7 @@ export class AddonCalendarProvider {
async getEventsList( async getEventsList(
initialTime?: number, initialTime?: number,
daysToStart: number = 0, daysToStart: number = 0,
daysInterval: number = AddonCalendarProvider.DAYS_INTERVAL, daysInterval: number = ADDON_CALENDAR_DAYS_INTERVAL,
siteId?: string, siteId?: string,
): Promise<AddonCalendarGetEventsEvent[]> { ): Promise<AddonCalendarGetEventsEvent[]> {
@ -891,7 +878,7 @@ export class AddonCalendarProvider {
cacheKey: this.getEventsListCacheKey(daysToStart, daysInterval), cacheKey: this.getEventsListCacheKey(daysToStart, daysInterval),
getCacheUsingCacheKey: true, getCacheUsingCacheKey: true,
uniqueCacheKey: true, uniqueCacheKey: true,
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
const response = const response =
await site.read<AddonCalendarGetCalendarEventsWSResponse>('core_calendar_get_calendar_events', params, preSets); await site.read<AddonCalendarGetCalendarEventsWSResponse>('core_calendar_get_calendar_events', params, preSets);
@ -907,7 +894,7 @@ export class AddonCalendarProvider {
* @returns Prefix Cache key. * @returns Prefix Cache key.
*/ */
protected getEventsListPrefixCacheKey(): string { protected getEventsListPrefixCacheKey(): string {
return ROOT_CACHE_KEY + 'events:'; return AddonCalendarProvider.ROOT_CACHE_KEY + 'events:';
} }
/** /**
@ -931,7 +918,7 @@ export class AddonCalendarProvider {
async getLocalEventsByRepeatIdFromLocalDb(repeatId: number, siteId?: string): Promise<AddonCalendarEventDBRecord[]> { async getLocalEventsByRepeatIdFromLocalDb(repeatId: number, siteId?: string): Promise<AddonCalendarEventDBRecord[]> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
return site.getDb().getRecords(EVENTS_TABLE, { repeatid: repeatId }); return site.getDb().getRecords(ADDON_CALENDAR_EVENTS_TABLE, { repeatid: repeatId });
} }
/** /**
@ -969,7 +956,7 @@ export class AddonCalendarProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getMonthlyEventsCacheKey(year, month, courseId, categoryId), cacheKey: this.getMonthlyEventsCacheKey(year, month, courseId, categoryId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
if (ignoreCache) { if (ignoreCache) {
preSets.getFromCache = false; preSets.getFromCache = false;
@ -985,7 +972,7 @@ export class AddonCalendarProvider {
// Store starting week day preference, we need it in offline to show months that are not in cache. // Store starting week day preference, we need it in offline to show months that are not in cache.
if (CoreNetwork.isOnline()) { if (CoreNetwork.isOnline()) {
CoreConfig.set(AddonCalendarProvider.STARTING_WEEK_DAY, response.daynames[0].dayno); CoreConfig.set(ADDON_CALENDAR_STARTING_WEEK_DAY, response.daynames[0].dayno);
} }
return response; return response;
@ -997,7 +984,7 @@ export class AddonCalendarProvider {
* @returns Prefix Cache key. * @returns Prefix Cache key.
*/ */
protected getMonthlyEventsPrefixCacheKey(): string { protected getMonthlyEventsPrefixCacheKey(): string {
return ROOT_CACHE_KEY + 'monthly:'; return AddonCalendarProvider.ROOT_CACHE_KEY + 'monthly:';
} }
/** /**
@ -1054,7 +1041,7 @@ export class AddonCalendarProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getUpcomingEventsCacheKey(courseId, categoryId), cacheKey: this.getUpcomingEventsCacheKey(courseId, categoryId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
if (ignoreCache) { if (ignoreCache) {
@ -1074,7 +1061,7 @@ export class AddonCalendarProvider {
* @returns Prefix Cache key. * @returns Prefix Cache key.
*/ */
protected getUpcomingEventsPrefixCacheKey(): string { protected getUpcomingEventsPrefixCacheKey(): string {
return ROOT_CACHE_KEY + 'upcoming:'; return AddonCalendarProvider.ROOT_CACHE_KEY + 'upcoming:';
} }
/** /**
@ -1120,7 +1107,7 @@ export class AddonCalendarProvider {
getWeekDays(startingDay?: number): AddonCalendarWeekDaysTranslationKeys[] { getWeekDays(startingDay?: number): AddonCalendarWeekDaysTranslationKeys[] {
startingDay = startingDay || 0; startingDay = startingDay || 0;
return this.weekDays.slice(startingDay).concat(this.weekDays.slice(0, startingDay)); return AddonCalendarProvider.weekDays.slice(startingDay).concat(AddonCalendarProvider.weekDays.slice(0, startingDay));
} }
/** /**
@ -1440,7 +1427,7 @@ export class AddonCalendarProvider {
await this.addDefaultEventReminder(eventRecord, site.getId()); await this.addDefaultEventReminder(eventRecord, site.getId());
} }
await site.getDb().insertRecord(EVENTS_TABLE, eventRecord); await site.getDb().insertRecord(ADDON_CALENDAR_EVENTS_TABLE, eventRecord);
} }
/** /**
@ -1451,7 +1438,7 @@ export class AddonCalendarProvider {
*/ */
protected async addDefaultEventReminder(event: AddonCalendarEventDBRecord, siteId?: string): Promise<void> { protected async addDefaultEventReminder(event: AddonCalendarEventDBRecord, siteId?: string): Promise<void> {
// Add default reminder if the event isn't stored already and doesn't have any reminder. // Add default reminder if the event isn't stored already and doesn't have any reminder.
const eventExist = await CoreUtils.promiseWorks(this.getEventFromLocalDb(event.id, siteId)); const eventExist = await CorePromiseUtils.promiseWorks(this.getEventFromLocalDb(event.id, siteId));
if (eventExist) { if (eventExist) {
return; return;
} }
@ -1522,7 +1509,7 @@ export class AddonCalendarProvider {
// Now save the reminders if any. // Now save the reminders if any.
if (options.reminders?.length) { if (options.reminders?.length) {
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
Promise.all(options.reminders.map((reminder) => Promise.all(options.reminders.map((reminder) =>
this.addEventReminder(event, reminder.time, siteId))), this.addEventReminder(event, reminder.time, siteId))),
); );
@ -1545,7 +1532,7 @@ export class AddonCalendarProvider {
// Now save the reminders if any. // Now save the reminders if any.
if (options.reminders?.length) { if (options.reminders?.length) {
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
Promise.all(options.reminders.map((reminder) => Promise.all(options.reminders.map((reminder) =>
this.addEventReminder(event, reminder.time, siteId))), this.addEventReminder(event, reminder.time, siteId))),
); );
@ -1553,7 +1540,7 @@ export class AddonCalendarProvider {
return ({ sent: true, event }); return ({ sent: true, event });
} catch (error) { } catch (error) {
if (error && !CoreUtils.isWebServiceError(error)) { if (error && !CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return storeOffline(); return storeOffline();
} else { } else {
@ -1591,7 +1578,7 @@ export class AddonCalendarProvider {
} }
const params: AddonCalendarSubmitCreateUpdateFormWSParams = { const params: AddonCalendarSubmitCreateUpdateFormWSParams = {
formdata: CoreUtils.objectToGetParams(formData), formdata: CoreObject.toGetParams(formData),
}; };
const result = const result =
await site.write<AddonCalendarSubmitCreateUpdateFormWSResponse>('core_calendar_submit_create_update_form', params); await site.write<AddonCalendarSubmitCreateUpdateFormWSResponse>('core_calendar_submit_create_update_form', params);
@ -1606,7 +1593,7 @@ export class AddonCalendarProvider {
if (eventId < 0) { if (eventId < 0) {
// Offline event has been sent. Change reminders instanceId if any. // Offline event has been sent. Change reminders instanceId if any.
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
CoreReminders.updateReminders( CoreReminders.updateReminders(
{ instanceId: result.event.id }, { instanceId: result.event.id },
{ {
@ -1620,7 +1607,7 @@ export class AddonCalendarProvider {
if (formData.id === 0) { if (formData.id === 0) {
// Store the new event in local DB. // Store the new event in local DB.
await CoreUtils.ignoreErrors(this.storeEventInLocalDb(result.event, { addDefaultReminder: false, siteId })); await CorePromiseUtils.ignoreErrors(this.storeEventInLocalDb(result.event, { addDefaultReminder: false, siteId }));
} }
return result.event; return result.event;
@ -2081,9 +2068,9 @@ export type AddonCalendarEventToDisplay = Partial<AddonCalendarCalendarEvent> &
/** /**
* Event triggered when an event is modified with event types: * Event triggered when an event is modified with event types:
* NEW_EVENT_EVENT, EDIT_EVENT_EVENT, DELETED_EVENT_EVENT, UNDELETED_EVENT_EVENT. * NEW_EVENT, EDIT_EVENT, DELETED_EVENT, UNDELETED_EVENT.
*/ */
export type AddonCalendarUpdatedEventEvent = { export type AddonCalendarUpdatedEvent = {
eventId: number; eventId: number;
oldEventId?: number; // Old event ID. Used when an offline event is sent. oldEventId?: number; // Old event ID. Used when an offline event is sent.
sent?: boolean; sent?: boolean;

View File

@ -13,7 +13,8 @@
// limitations under the License. // limitations under the License.
import { CoreSiteSchema } from '@services/sites'; import { CoreSiteSchema } from '@services/sites';
import { AddonCalendarEventType } from '../calendar'; import { AddonCalendarEventType } from '@addons/calendar/constants';
/** /**
* Database variables for AddonDatabaseOffline service. * Database variables for AddonDatabaseOffline service.
*/ */

View File

@ -12,24 +12,24 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { ADDON_CALENDAR_EVENTS_TABLE, AddonCalendarEventType } from '@addons/calendar/constants';
import { SQLiteDB } from '@classes/sqlitedb'; import { SQLiteDB } from '@classes/sqlitedb';
import { CoreRemindersService, CoreReminders } from '@features/reminders/services/reminders'; import { REMINDERS_DISABLED } from '@features/reminders/constants';
import { CoreReminders } from '@features/reminders/services/reminders';
import { CoreConfig } from '@services/config'; import { CoreConfig } from '@services/config';
import { CoreSiteSchema } from '@services/sites'; import { CoreSiteSchema } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { AddonCalendarEventType } from '../calendar';
/** /**
* Database variables for AddonCalendarProvider service. * Database variables for AddonCalendarProvider service.
*/ */
export const EVENTS_TABLE = 'addon_calendar_events_3';
export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = { export const CALENDAR_SITE_SCHEMA: CoreSiteSchema = {
name: 'AddonCalendarProvider', name: 'AddonCalendarProvider',
version: 5, version: 5,
canBeCleared: [EVENTS_TABLE], canBeCleared: [ADDON_CALENDAR_EVENTS_TABLE],
tables: [ tables: [
{ {
name: EVENTS_TABLE, name: ADDON_CALENDAR_EVENTS_TABLE,
columns: [ columns: [
{ {
name: 'id', name: 'id',
@ -199,10 +199,10 @@ const migrateDefaultTime = async (siteId: string, convertToSeconds = false): Pro
const key = 'mmaCalendarDefaultNotifTime#' + siteId; const key = 'mmaCalendarDefaultNotifTime#' + siteId;
try { try {
let defaultTime = await CoreConfig.get<number>(key); let defaultTime = await CoreConfig.get<number>(key);
await CoreUtils.ignoreErrors(CoreConfig.delete(key)); await CorePromiseUtils.ignoreErrors(CoreConfig.delete(key));
if (defaultTime <= 0) { if (defaultTime <= 0) {
defaultTime = CoreRemindersService.DISABLED; defaultTime = REMINDERS_DISABLED;
} else if (convertToSeconds) { } else if (convertToSeconds) {
// Convert from minutes to seconds. // Convert from minutes to seconds.
defaultTime = defaultTime * 60; defaultTime = defaultTime * 60;

View File

@ -16,6 +16,7 @@ import { Injectable } from '@angular/core';
import { AddonCalendar } from '../calendar'; import { AddonCalendar } from '../calendar';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@features/mainmenu/services/mainmenu-delegate'; import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@features/mainmenu/services/mainmenu-delegate';
import { ADDON_CALENDAR_PAGE_NAME } from '@addons/calendar/constants';
/** /**
* Handler to inject an option into main menu. * Handler to inject an option into main menu.
@ -23,8 +24,6 @@ import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@features/mainmenu
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonCalendarMainMenuHandlerService implements CoreMainMenuHandler { export class AddonCalendarMainMenuHandlerService implements CoreMainMenuHandler {
static readonly PAGE_NAME = 'calendar';
name = 'AddonCalendar'; name = 'AddonCalendar';
priority = 550; priority = 550;
@ -46,7 +45,7 @@ export class AddonCalendarMainMenuHandlerService implements CoreMainMenuHandler
return { return {
icon: 'far-calendar', icon: 'far-calendar',
title: 'addon.calendar.calendar', title: 'addon.calendar.calendar',
page: AddonCalendarMainMenuHandlerService.PAGE_NAME, page: ADDON_CALENDAR_PAGE_NAME,
class: 'addon-calendar-handler', class: 'addon-calendar-handler',
}; };
} }

View File

@ -14,7 +14,7 @@
import { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source'; import { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source';
import { CoreUserProfile } from '@features/user/services/user'; import { CoreUserProfile } from '@features/user/services/user';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { import {
AddonCompetency, AddonCompetency,
AddonCompetencyDataForCourseCompetenciesPageCompetency, AddonCompetencyDataForCourseCompetenciesPageCompetency,
@ -70,7 +70,7 @@ export class AddonCompetencyCourseCompetenciesSource
* Invalidate course cache. * Invalidate course cache.
*/ */
async invalidateCache(): Promise<void> { async invalidateCache(): Promise<void> {
await CoreUtils.ignoreErrors(AddonCompetency.invalidateCourseCompetencies(this.COURSE_ID, this.USER_ID)); await CorePromiseUtils.ignoreErrors(AddonCompetency.invalidateCourseCompetencies(this.COURSE_ID, this.USER_ID));
} }
/** /**

View File

@ -14,7 +14,7 @@
import { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source'; import { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source';
import { CoreUserProfile } from '@features/user/services/user'; import { CoreUserProfile } from '@features/user/services/user';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { import {
AddonCompetency, AddonCompetency,
AddonCompetencyDataForPlanPageCompetency, AddonCompetencyDataForPlanPageCompetency,
@ -60,7 +60,7 @@ export class AddonCompetencyPlanCompetenciesSource extends CoreRoutedItemsManage
* Invalidate plan cache. * Invalidate plan cache.
*/ */
async invalidateCache(): Promise<void> { async invalidateCache(): Promise<void> {
await CoreUtils.ignoreErrors(AddonCompetency.invalidateLearningPlan(this.PLAN_ID)); await CorePromiseUtils.ignoreErrors(AddonCompetency.invalidateLearningPlan(this.PLAN_ID));
} }
/** /**

View File

@ -31,4 +31,4 @@ const routes: Routes = [
AddonCompetencyCourseCompetenciesPageModule, AddonCompetencyCourseCompetenciesPageModule,
], ],
}) })
export class AddonCompetencyCourseContentsLazyModule {} export default class AddonCompetencyCourseContentsLazyModule {}

View File

@ -69,4 +69,4 @@ const routes: Routes = [
AddonCompetencyCompetencySummaryPageModule, AddonCompetencyCompetencySummaryPageModule,
], ],
}) })
export class AddonCompetencyCourseDetailsLazyModule {} export default class AddonCompetencyCourseDetailsLazyModule {}

View File

@ -89,4 +89,4 @@ const routes: Routes = [
AddonCompetencyPlanListPage, AddonCompetencyPlanListPage,
], ],
}) })
export class AddonCompetencyLearningPlansLazyModule {} export default class AddonCompetencyLearningPlansLazyModule {}

View File

@ -28,7 +28,7 @@ import { Routes } from '@angular/router';
import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module'; import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module';
import { CoreCourseIndexRoutingModule } from '@features/course/course-routing.module'; import { CoreCourseIndexRoutingModule } from '@features/course/course-routing.module';
import { PARTICIPANTS_PAGE_NAME } from '@features/user/constants'; import { PARTICIPANTS_PAGE_NAME } from '@features/user/constants';
import { COURSE_PAGE_NAME } from '@features/course/constants'; import { CORE_COURSE_PAGE_NAME } from '@features/course/constants';
import { ADDON_COMPETENCY_LEARNING_PLANS_PAGE, ADDON_COMPETENCY_COMPETENCIES_PAGE } from './constants'; import { ADDON_COMPETENCY_LEARNING_PLANS_PAGE, ADDON_COMPETENCY_COMPETENCIES_PAGE } from './constants';
/** /**
@ -49,22 +49,22 @@ export async function getCompetencyServices(): Promise<Type<unknown>[]> {
const mainMenuChildrenRoutes: Routes = [ const mainMenuChildrenRoutes: Routes = [
{ {
path: ADDON_COMPETENCY_LEARNING_PLANS_PAGE, path: ADDON_COMPETENCY_LEARNING_PLANS_PAGE,
loadChildren: () => import('./competency-learning-plans-lazy.module').then(m => m.AddonCompetencyLearningPlansLazyModule), loadChildren: () => import('./competency-learning-plans-lazy.module'),
}, },
{ {
path: `${COURSE_PAGE_NAME}/:courseId/${ADDON_COMPETENCY_COMPETENCIES_PAGE}`, path: `${CORE_COURSE_PAGE_NAME}/:courseId/${ADDON_COMPETENCY_COMPETENCIES_PAGE}`,
loadChildren: () => import('./competency-course-details-lazy.module').then(m => m.AddonCompetencyCourseDetailsLazyModule), loadChildren: () => import('./competency-course-details-lazy.module'),
}, },
{ {
path: `${COURSE_PAGE_NAME}/:courseId/${PARTICIPANTS_PAGE_NAME}/:userId/${ADDON_COMPETENCY_COMPETENCIES_PAGE}`, path: `${CORE_COURSE_PAGE_NAME}/:courseId/${PARTICIPANTS_PAGE_NAME}/:userId/${ADDON_COMPETENCY_COMPETENCIES_PAGE}`,
loadChildren: () => import('./competency-course-details-lazy.module').then(m => m.AddonCompetencyCourseDetailsLazyModule), loadChildren: () => import('./competency-course-details-lazy.module'),
}, },
]; ];
const courseIndexRoutes: Routes = [ const courseIndexRoutes: Routes = [
{ {
path: ADDON_COMPETENCY_COMPETENCIES_PAGE, path: ADDON_COMPETENCY_COMPETENCIES_PAGE,
loadChildren: () => import('./competency-course-contents-lazy.module').then(m => m.AddonCompetencyCourseContentsLazyModule), loadChildren: () => import('./competency-course-contents-lazy.module'),
}, },
]; ];

View File

@ -31,7 +31,7 @@ import {
} from '@addons/competency/services/competency'; } from '@addons/competency/services/competency';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { ContextLevel } from '@/core/constants'; import { ContextLevel } from '@/core/constants';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { ADDON_COMPETENCY_SUMMARY_PAGE } from '@addons/competency/constants'; import { ADDON_COMPETENCY_SUMMARY_PAGE } from '@addons/competency/constants';
import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager'; import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager';
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker'; import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
@ -175,7 +175,7 @@ export class AddonCompetencyCompetencyPage implements OnInit, OnDestroy {
async refreshCompetency(refresher: HTMLIonRefresherElement): Promise<void> { async refreshCompetency(refresher: HTMLIonRefresherElement): Promise<void> {
const source = this.competencies.getSource(); const source = this.competencies.getSource();
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
source instanceof AddonCompetencyPlanCompetenciesSource source instanceof AddonCompetencyPlanCompetenciesSource
? AddonCompetency.invalidateCompetencyInPlan(source.PLAN_ID, this.requireCompetencyId()) ? AddonCompetency.invalidateCompetencyInPlan(source.PLAN_ID, this.requireCompetencyId())
: AddonCompetency.invalidateCompetencyInCourse(source.COURSE_ID, this.requireCompetencyId(), source.USER_ID), : AddonCompetency.invalidateCompetencyInCourse(source.COURSE_ID, this.requireCompetencyId(), source.USER_ID),
@ -287,7 +287,7 @@ export class AddonCompetencyCompetencyPage implements OnInit, OnDestroy {
return; return;
} }
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
AddonCompetency.logCompetencyInPlanView(source.PLAN_ID, compId, this.planStatus, name, userId), AddonCompetency.logCompetencyInPlanView(source.PLAN_ID, compId, this.planStatus, name, userId),
); );
@ -316,7 +316,9 @@ export class AddonCompetencyCompetencyPage implements OnInit, OnDestroy {
return; return;
} }
await CoreUtils.ignoreErrors(AddonCompetency.logCompetencyInCourseView(source.COURSE_ID, compId, name, source.USER_ID)); await CorePromiseUtils.ignoreErrors(
AddonCompetency.logCompetencyInCourseView(source.COURSE_ID, compId, name, source.USER_ID),
);
CoreAnalytics.logEvent({ CoreAnalytics.logEvent({
type: CoreAnalyticsEventType.VIEW_ITEM, type: CoreAnalyticsEventType.VIEW_ITEM,

View File

@ -17,7 +17,7 @@ import { ContextLevel } from '@/core/constants';
import { AddonCompetencySummary, AddonCompetency } from '@addons/competency/services/competency'; import { AddonCompetencySummary, AddonCompetency } from '@addons/competency/services/competency';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { ADDON_COMPETENCY_SUMMARY_PAGE } from '@addons/competency/constants'; import { ADDON_COMPETENCY_SUMMARY_PAGE } from '@addons/competency/constants';
import { CoreTime } from '@singletons/time'; import { CoreTime } from '@singletons/time';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
@ -45,7 +45,7 @@ export class AddonCompetencyCompetencySummaryPage implements OnInit {
return; return;
} }
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
AddonCompetency.logCompetencyView(this.competencyId, this.competency.competency.shortname), AddonCompetency.logCompetencyView(this.competencyId, this.competency.competency.shortname),
); );

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { CoreCacheUpdateFrequency } from '@/core/constants';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
@ -19,7 +20,7 @@ import { CoreCommentsArea } from '@features/comments/services/comments';
import { CoreCourseSummary } from '@features/course/services/course'; import { CoreCourseSummary } from '@features/course/services/course';
import { CoreUserSummary } from '@features/user/services/user'; import { CoreUserSummary } from '@features/user/services/user';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
const ROOT_CACHE_KEY = 'mmaCompetency:'; const ROOT_CACHE_KEY = 'mmaCompetency:';
@ -188,7 +189,7 @@ export class AddonCompetencyProvider {
return false; return false;
} }
return CoreUtils.promiseWorks(this.getCourseCompetencies(courseId, undefined, siteId)); return CorePromiseUtils.promiseWorks(this.getCourseCompetencies(courseId, undefined, siteId));
} }
/** /**
@ -208,7 +209,7 @@ export class AddonCompetencyProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getLearningPlansCacheKey(userId), cacheKey: this.getLearningPlansCacheKey(userId),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
const response = await site.read<AddonCompetencyDataForPlansPageWSResponse>('tool_lp_data_for_plans_page', params, preSets); const response = await site.read<AddonCompetencyDataForPlansPageWSResponse>('tool_lp_data_for_plans_page', params, preSets);
@ -232,7 +233,7 @@ export class AddonCompetencyProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getLearningPlanCacheKey(planId), cacheKey: this.getLearningPlanCacheKey(planId),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
return site.read('tool_lp_data_for_plan_page', params, preSets); return site.read('tool_lp_data_for_plan_page', params, preSets);
@ -260,7 +261,7 @@ export class AddonCompetencyProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCompetencyInPlanCacheKey(planId, competencyId), cacheKey: this.getCompetencyInPlanCacheKey(planId, competencyId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
return site.read( return site.read(
@ -298,7 +299,7 @@ export class AddonCompetencyProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCompetencyInCourseCacheKey(courseId, competencyId, userId), cacheKey: this.getCompetencyInCourseCacheKey(courseId, competencyId, userId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
if (ignoreCache) { if (ignoreCache) {
@ -334,7 +335,7 @@ export class AddonCompetencyProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCompetencySummaryCacheKey(competencyId, userId), cacheKey: this.getCompetencySummaryCacheKey(competencyId, userId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
if (ignoreCache) { if (ignoreCache) {
@ -400,7 +401,7 @@ export class AddonCompetencyProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCourseCompetenciesCacheKey(courseId), cacheKey: this.getCourseCompetenciesCacheKey(courseId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
if (ignoreCache) { if (ignoreCache) {

View File

@ -16,7 +16,7 @@ import { ADDON_COMPETENCY_COMPETENCIES_PAGE, ADDON_COMPETENCY_LEARNING_PLANS_PAG
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base-handler'; import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base-handler';
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate'; import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { COURSE_PAGE_NAME } from '@features/course/constants'; import { CORE_COURSE_PAGE_NAME } from '@features/course/constants';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonCompetency } from '../competency'; import { AddonCompetency } from '../competency';
@ -41,7 +41,7 @@ export class AddonCompetencyCompetencyLinkHandlerService extends CoreContentLink
action: async (siteId: string): Promise<void> => { action: async (siteId: string): Promise<void> => {
if (courseId) { if (courseId) {
await CoreNavigator.navigateToSitePath( await CoreNavigator.navigateToSitePath(
`${COURSE_PAGE_NAME}/${courseId}/${ADDON_COMPETENCY_COMPETENCIES_PAGE}`, `${CORE_COURSE_PAGE_NAME}/${courseId}/${ADDON_COMPETENCY_COMPETENCIES_PAGE}`,
{ {
params: { userId: params.userid }, params: { userId: params.userid },
siteId, siteId,

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseAccessDataType } from '@features/course/services/course'; import { CoreCourseAccessDataType } from '@features/course/constants';
import { import {
CoreCourseAccess, CoreCourseAccess,
CoreCourseOptionsHandler, CoreCourseOptionsHandler,

View File

@ -14,14 +14,15 @@
import { ADDON_COMPETENCY_COMPETENCIES_PAGE, ADDON_COMPETENCY_LEARNING_PLANS_PAGE } from '@addons/competency/constants'; import { ADDON_COMPETENCY_COMPETENCIES_PAGE, ADDON_COMPETENCY_LEARNING_PLANS_PAGE } from '@addons/competency/constants';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { COURSE_PAGE_NAME } from '@features/course/constants'; import { CORE_COURSE_PAGE_NAME } from '@features/course/constants';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonCompetency } from '../competency'; import { AddonCompetency } from '../competency';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Handler for competencies push notifications clicks. * Handler for competencies push notifications clicks.
@ -55,7 +56,7 @@ export class AddonCompetencyPushClickHandlerService implements CorePushNotificat
// Open the learning plan. // Open the learning plan.
const planId = Number(contextUrlParams.id); const planId = Number(contextUrlParams.id);
await CoreUtils.ignoreErrors(AddonCompetency.invalidateLearningPlan(planId, notification.site)); await CorePromiseUtils.ignoreErrors(AddonCompetency.invalidateLearningPlan(planId, notification.site));
await CoreNavigator.navigateToSitePath(`${ADDON_COMPETENCY_LEARNING_PLANS_PAGE}/${planId}`, { await CoreNavigator.navigateToSitePath(`${ADDON_COMPETENCY_LEARNING_PLANS_PAGE}/${planId}`, {
siteId: notification.site, siteId: notification.site,
@ -71,11 +72,13 @@ export class AddonCompetencyPushClickHandlerService implements CorePushNotificat
const planId = Number(contextUrlParams.planid); const planId = Number(contextUrlParams.planid);
const userId = Number(contextUrlParams.userid); const userId = Number(contextUrlParams.userid);
await CoreUtils.ignoreErrors(AddonCompetency.invalidateCompetencyInPlan(planId, competencyId, notification.site)); await CorePromiseUtils.ignoreErrors(
AddonCompetency.invalidateCompetencyInPlan(planId, competencyId, notification.site),
);
if (courseId) { if (courseId) {
await CoreNavigator.navigateToSitePath( await CoreNavigator.navigateToSitePath(
`${COURSE_PAGE_NAME}/${courseId}/${ADDON_COMPETENCY_COMPETENCIES_PAGE}/${competencyId}`, `${CORE_COURSE_PAGE_NAME}/${courseId}/${ADDON_COMPETENCY_COMPETENCIES_PAGE}/${competencyId}`,
{ {
params: { userId }, params: { userId },
siteId: notification.site, siteId: notification.site,
@ -101,7 +104,7 @@ export class AddonCompetencyPushClickHandlerService implements CorePushNotificat
// Open the list of plans. // Open the list of plans.
const userId = Number(contextUrlParams.userid); const userId = Number(contextUrlParams.userid);
await CoreUtils.ignoreErrors(AddonCompetency.invalidateLearningPlans(userId, notification.site)); await CorePromiseUtils.ignoreErrors(AddonCompetency.invalidateLearningPlans(userId, notification.site));
await CoreNavigator.navigateToSitePath(ADDON_COMPETENCY_LEARNING_PLANS_PAGE, { await CoreNavigator.navigateToSitePath(ADDON_COMPETENCY_LEARNING_PLANS_PAGE, {
params: { userId }, params: { userId },

View File

@ -14,7 +14,7 @@
import { ADDON_COMPETENCY_COMPETENCIES_PAGE, ADDON_COMPETENCY_LEARNING_PLANS_PAGE } from '@addons/competency/constants'; import { ADDON_COMPETENCY_COMPETENCIES_PAGE, ADDON_COMPETENCY_LEARNING_PLANS_PAGE } from '@addons/competency/constants';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { COURSE_PAGE_NAME } from '@features/course/constants'; import { CORE_COURSE_PAGE_NAME } from '@features/course/constants';
import { CoreUserProfile } from '@features/user/services/user'; import { CoreUserProfile } from '@features/user/services/user';
import { import {
CoreUserProfileHandler, CoreUserProfileHandler,
@ -112,9 +112,13 @@ export class AddonCompetencyUserHandlerService implements CoreUserProfileHandler
action: (event, user, context, contextId): void => { action: (event, user, context, contextId): void => {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
CoreNavigator.navigateToSitePath( CoreNavigator.navigateToSitePath([
[COURSE_PAGE_NAME, contextId, PARTICIPANTS_PAGE_NAME, user.id, ADDON_COMPETENCY_COMPETENCIES_PAGE].join('/'), CORE_COURSE_PAGE_NAME,
); contextId,
PARTICIPANTS_PAGE_NAME,
user.id,
ADDON_COMPETENCY_COMPETENCIES_PAGE,
].join('/'));
}, },
}; };
} }

View File

@ -37,4 +37,4 @@ const routes: Routes = [
AddonCourseCompletionReportPage, AddonCourseCompletionReportPage,
], ],
}) })
export class AddonCourseCompletionLazyModule {} export default class AddonCourseCompletionLazyModule {}

View File

@ -39,7 +39,7 @@ export async function getCourseCompletionServices(): Promise<Type<unknown>[]> {
const routes: Routes = [ const routes: Routes = [
{ {
path: 'coursecompletion', path: 'coursecompletion',
loadChildren: () => import('./coursecompletion-lazy.module').then(m => m.AddonCourseCompletionLazyModule), loadChildren: () => import('./coursecompletion-lazy.module'),
}, },
]; ];

View File

@ -15,7 +15,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites'; import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CoreWSError } from '@classes/errors/wserror';
import { CoreCourseAnyCourseData, CoreCourses } from '@features/courses/services/courses'; import { CoreCourseAnyCourseData, CoreCourses } from '@features/courses/services/courses';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
import { CoreStatusWithWarningsWSResponse, CoreWSExternalWarning } from '@services/ws'; import { CoreStatusWithWarningsWSResponse, CoreWSExternalWarning } from '@services/ws';
@ -25,6 +25,7 @@ import { asyncObservable } from '@/core/utils/rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { CoreSiteWSPreSets, WSObservable } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets, WSObservable } from '@classes/sites/authenticated-site';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { CoreCacheUpdateFrequency } from '@/core/constants';
const ROOT_CACHE_KEY = 'mmaCourseCompletion:'; const ROOT_CACHE_KEY = 'mmaCourseCompletion:';
@ -173,7 +174,7 @@ export class AddonCourseCompletionProvider {
const preSets = { const preSets = {
...(options.preSets ?? {}), ...(options.preSets ?? {}),
cacheKey: this.getCompletionCacheKey(courseId, userId), cacheKey: this.getCompletionCacheKey(courseId, userId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
cacheErrors: ['notenroled'], cacheErrors: ['notenroled'],
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), ...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
}; };
@ -283,7 +284,7 @@ export class AddonCourseCompletionProvider {
return true; return true;
} catch (error) { } catch (error) {
if (CoreUtils.isWebServiceError(error)) { if (CoreWSError.isWebServiceError(error)) {
// The WS returned an error, plugin is not enabled. // The WS returned an error, plugin is not enabled.
return false; return false;
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseAccessDataType } from '@features/course/services/course'; import { CoreCourseAccessDataType } from '@features/course/constants';
import { import {
CoreCourseAccess, CoreCourseAccess,
CoreCourseOptionsHandler, CoreCourseOptionsHandler,

View File

@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { CoreCacheUpdateFrequency } from '@/core/constants';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreSite } from '@classes/sites/site';
import { CoreEnrolEnrolmentInfo } from '@features/enrol/services/enrol'; import { CoreEnrolEnrolmentInfo } from '@features/enrol/services/enrol';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreWSExternalWarning } from '@services/ws'; import { CoreWSExternalWarning } from '@services/ws';
@ -44,7 +44,7 @@ export class AddonEnrolGuestService {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getGuestEnrolmentInfoCacheKey(instanceId), cacheKey: this.getGuestEnrolmentInfoCacheKey(instanceId),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
const response = const response =
@ -68,15 +68,11 @@ export class AddonEnrolGuestService {
* *
* @param instanceId Guest instance ID. * @param instanceId Guest instance ID.
* @param siteId Site Id. If not defined, use current site. * @param siteId Site Id. If not defined, use current site.
* @returns Promise resolved when the data is invalidated.
*/ */
async invalidateGuestEnrolmentInfo(instanceId: number, siteId?: string): Promise<void> { async invalidateGuestEnrolmentInfo(instanceId: number, siteId?: string): Promise<void> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
await Promise.all([ await site.invalidateWsCacheForKey(this.getGuestEnrolmentInfoCacheKey(instanceId));
site.invalidateWsCacheForKey(this.getGuestEnrolmentInfoCacheKey(instanceId)),
site.invalidateWsCacheForKey(`mmCourses:guestinfo:${instanceId}`), // @todo Remove after 4.3 release.
]);
} }
/** /**

View File

@ -17,11 +17,11 @@ import { CoreEnrolAction, CoreEnrolSelfHandler, CoreEnrolInfoIcon } from '@featu
import { Translate, makeSingleton } from '@singletons'; import { Translate, makeSingleton } from '@singletons';
import { AddonEnrolSelf } from './self'; import { AddonEnrolSelf } from './self';
import { CorePasswordModalResponse } from '@components/password-modal/password-modal'; import { CorePasswordModalResponse } from '@components/password-modal/password-modal';
import { CoreCoursesProvider } from '@features/courses/services/courses';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreEnrol, CoreEnrolEnrolmentMethod } from '@features/enrol/services/enrol'; import { CoreEnrol, CoreEnrolEnrolmentMethod } from '@features/enrol/services/enrol';
import { CoreModals } from '@services/modals'; import { CoreModals } from '@services/modals';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import { CORE_COURSES_ENROL_INVALID_KEY } from '@features/courses/constants';
/** /**
* Enrol handler. * Enrol handler.
@ -122,7 +122,7 @@ export class AddonEnrolSelfHandlerService implements CoreEnrolSelfHandler {
try { try {
response.validated = await AddonEnrolSelf.selfEnrol(method.courseid, password, method.id); response.validated = await AddonEnrolSelf.selfEnrol(method.courseid, password, method.id);
} catch (error) { } catch (error) {
if (error && error.errorcode === CoreCoursesProvider.ENROL_INVALID_KEY) { if (error && error.errorcode === CORE_COURSES_ENROL_INVALID_KEY) {
response.validated = false; response.validated = false;
response.error = error.message; response.error = error.message;
} else { } else {

View File

@ -12,11 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { CoreCacheUpdateFrequency } from '@/core/constants';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreWSError } from '@classes/errors/wserror'; import { CoreWSError } from '@classes/errors/wserror';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreSite } from '@classes/sites/site'; import { CORE_COURSES_ENROL_INVALID_KEY } from '@features/courses/constants';
import { CoreCoursesProvider } from '@features/courses/services/courses';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreStatusWithWarningsWSResponse } from '@services/ws'; import { CoreStatusWithWarningsWSResponse } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
@ -45,7 +45,7 @@ export class AddonEnrolSelfService {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getSelfEnrolmentInfoCacheKey(instanceId), cacheKey: this.getSelfEnrolmentInfoCacheKey(instanceId),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
return await site.read<AddonEnrolSelfGetInstanceInfoWSResponse>('enrol_self_get_instance_info', params, preSets); return await site.read<AddonEnrolSelfGetInstanceInfoWSResponse>('enrol_self_get_instance_info', params, preSets);
@ -82,7 +82,7 @@ export class AddonEnrolSelfService {
* @param instanceId Enrol instance ID. * @param instanceId Enrol instance ID.
* @param siteId Site ID. If not defined, use current site. * @param siteId Site ID. If not defined, use current site.
* @returns Promise resolved if the user is enrolled. If the password is invalid, the promise is rejected * @returns Promise resolved if the user is enrolled. If the password is invalid, the promise is rejected
* with an object with errorcode = CoreCoursesProvider.ENROL_INVALID_KEY. * with an object with errorcode = CORE_COURSES_ENROL_INVALID_KEY.
*/ */
async selfEnrol(courseId: number, password: string = '', instanceId?: number, siteId?: string): Promise<boolean> { async selfEnrol(courseId: number, password: string = '', instanceId?: number, siteId?: string): Promise<boolean> {
@ -112,7 +112,7 @@ export class AddonEnrolSelfService {
warning.warningcode == '2' || warning.warningcode == '3' || warning.warningcode == '4'); warning.warningcode == '2' || warning.warningcode == '3' || warning.warningcode == '4');
if (warning) { if (warning) {
throw new CoreWSError({ errorcode: CoreCoursesProvider.ENROL_INVALID_KEY, message: warning.message }); throw new CoreWSError({ errorcode: CORE_COURSES_ENROL_INVALID_KEY, message: warning.message });
} else { } else {
throw new CoreWSError(response.warnings[0]); throw new CoreWSError(response.warnings[0]);
} }

View File

@ -19,7 +19,7 @@ import { CoreFilterFilter, CoreFilterFormatTextOptions } from '@features/filter/
import { CoreLang } from '@services/lang'; import { CoreLang } from '@services/lang';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
@ -180,7 +180,7 @@ export class AddonFilterMathJaxLoaderHandlerService extends CoreFilterDefaultHan
// Make sure the element is in DOM, otherwise some equations don't work. // Make sure the element is in DOM, otherwise some equations don't work.
// Automatically timeout the promise after a certain time, we don't want to wait forever. // Automatically timeout the promise after a certain time, we don't want to wait forever.
await CoreUtils.ignoreErrors(CoreUtils.timeoutPromise(CoreDom.waitToBeInDOM(container), 15000)); await CorePromiseUtils.ignoreErrors(CorePromiseUtils.timeoutPromise(CoreDom.waitToBeInDOM(container), 15000));
await this.window.M!.filter_mathjaxloader!.typeset(container); await this.window.M!.filter_mathjaxloader!.typeset(container);
} }
@ -336,7 +336,7 @@ export class AddonFilterMathJaxLoaderHandlerService extends CoreFilterDefaultHan
} }
await CoreWait.wait(250); await CoreWait.wait(250);
await CoreUtils.ignoreErrors(this.waitForReady(retries + 1)); await CorePromiseUtils.ignoreErrors(this.waitForReady(retries + 1));
} }
/** /**

View File

@ -17,7 +17,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications'; import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
import { AddonMessageOutputAirnotifier, AddonMessageOutputAirnotifierDevice } from '../../services/airnotifier'; import { AddonMessageOutputAirnotifier, AddonMessageOutputAirnotifierDevice } from '../../services/airnotifier';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Page that displays the list of devices. * Page that displays the list of devices.
@ -112,7 +112,7 @@ export class AddonMessageOutputAirnotifierDevicesPage implements OnInit, OnDestr
* Fetch devices. The purpose is to store the updated data, it won't be reflected in the view. * Fetch devices. The purpose is to store the updated data, it won't be reflected in the view.
*/ */
protected async updateDevices(): Promise<void> { protected async updateDevices(): Promise<void> {
await CoreUtils.ignoreErrors(AddonMessageOutputAirnotifier.invalidateUserDevices()); await CorePromiseUtils.ignoreErrors(AddonMessageOutputAirnotifier.invalidateUserDevices());
await AddonMessageOutputAirnotifier.getUserDevices(); await AddonMessageOutputAirnotifier.getUserDevices();
} }
@ -124,7 +124,7 @@ export class AddonMessageOutputAirnotifierDevicesPage implements OnInit, OnDestr
*/ */
async refreshDevices(refresher: HTMLIonRefresherElement): Promise<void> { async refreshDevices(refresher: HTMLIonRefresherElement): Promise<void> {
try { try {
await CoreUtils.ignoreErrors(AddonMessageOutputAirnotifier.invalidateUserDevices()); await CorePromiseUtils.ignoreErrors(AddonMessageOutputAirnotifier.invalidateUserDevices());
await this.fetchDevices(); await this.fetchDevices();
} finally { } finally {

View File

@ -16,14 +16,13 @@ import { Injectable } from '@angular/core';
import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSites, CoreSitesCommonWSOptions, CoreSitesReadingStrategy } from '@services/sites';
import { CoreWSExternalWarning } from '@services/ws'; import { CoreWSExternalWarning } from '@services/ws';
import { CoreConstants } from '@/core/constants'; import { CoreCacheUpdateFrequency, CoreConstants } from '@/core/constants';
import { CoreSite } from '@classes/sites/site';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { CoreWSError } from '@classes/errors/wserror'; import { CoreWSError } from '@classes/errors/wserror';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { CoreEvents, CoreEventSiteData } from '@singletons/events'; import { CoreEvents, CoreEventSiteData } from '@singletons/events';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreOpener } from '@singletons/opener';
import { CorePath } from '@singletons/path'; import { CorePath } from '@singletons/path';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
@ -102,7 +101,7 @@ export class AddonMessageOutputAirnotifierProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getSystemConfiguredCacheKey(), cacheKey: this.getSystemConfiguredCacheKey(),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets. ...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
}; };
@ -136,7 +135,7 @@ export class AddonMessageOutputAirnotifierProvider {
}; };
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getUserDevicesCacheKey(), cacheKey: this.getUserDevicesCacheKey(),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
}; };
if (ignoreCache) { if (ignoreCache) {
@ -223,7 +222,7 @@ export class AddonMessageOutputAirnotifierProvider {
); );
// Don't try auto-login, admins cannot use it. // Don't try auto-login, admins cannot use it.
CoreUtils.openInBrowser(url, { CoreOpener.openInBrowser(url, {
showBrowserWarning: false, showBrowserWarning: false,
}); });
}, },

View File

@ -0,0 +1,52 @@
// (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.
export const ADDON_MESSAGES_NEW_MESSAGE_EVENT = 'addon_messages_new_message_event';
export const ADDON_MESSAGES_READ_CHANGED_EVENT = 'addon_messages_read_changed_event';
// Notify a conversation should be opened.
export const ADDON_MESSAGES_OPEN_CONVERSATION_EVENT = 'addon_messages_open_conversation_event';
export const ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT = 'addon_messages_update_conversation_list_event';
export const ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT = 'addon_messages_member_changed_event';
export const ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT = 'addon_messages_unread_conversation_counts_event';
export const ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT = 'addon_messages_contact_requests_count_event';
export const ADDON_MESSAGES_POLL_INTERVAL = 10000;
export const ADDON_MESSAGES_PUSH_SIMULATION_COMPONENT = 'AddonMessagesPushSimulation';
export const enum AddonMessagesMessagePrivacy {
COURSEMEMBER = 0, // Privacy setting for being messaged by anyone within courses user is member.
ONLYCONTACTS = 1, // Privacy setting for being messaged only by contacts.
SITE = 2, // Privacy setting for being messaged by anyone on the site.
}
export const enum AddonMessagesMessageConversationType {
INDIVIDUAL = 1, // An individual conversation.
GROUP = 2, // A group conversation.
SELF = 3, // A self conversation.
}
export const ADDON_MESSAGES_LIMIT_CONTACTS = 50;
export const ADDON_MESSAGES_LIMIT_MESSAGES = 50;
export const ADDON_MESSAGES_LIMIT_INITIAL_USER_SEARCH = 3;
export const ADDON_MESSAGES_LIMIT_SEARCH = 50;
export const ADDON_MESSAGES_NOTIFICATION_PREFERENCES_KEY = 'message_provider_moodle_instantmessage';
export const ADDON_MESSAGES_AUTO_SYNCED = 'addon_messages_autom_synced';
export const enum AddonMessagesUpdateConversationAction {
MUTE = 'mute',
FAVOURITE = 'favourite',
DELETE = 'delete',
}

View File

@ -117,7 +117,7 @@ function buildRoutes(injector: Injector): Routes {
...discussionRoutes, ...discussionRoutes,
{ {
path: 'message-settings', path: 'message-settings',
loadChildren: () => import('./messages-settings-lazy.module').then(m => m.AddonMessagesSettingsLazyModule), loadChildren: () => import('./messages-settings-lazy.module'),
}, },
...buildTabMainRoutes(injector, { ...buildTabMainRoutes(injector, {
canActivate: [messagesIndexGuard], canActivate: [messagesIndexGuard],
@ -148,4 +148,4 @@ function buildRoutes(injector: Injector): Routes {
}, },
], ],
}) })
export class AddonMessagesLazyModule {} export default class AddonMessagesLazyModule {}

View File

@ -34,4 +34,4 @@ const routes: Routes = [
AddonMessagesSettingsPage, AddonMessagesSettingsPage,
], ],
}) })
export class AddonMessagesSettingsLazyModule {} export default class AddonMessagesSettingsLazyModule {}

View File

@ -58,13 +58,13 @@ export async function getMessagesServices(): Promise<Type<unknown>[]> {
const mainMenuChildrenRoutes: Routes = [ const mainMenuChildrenRoutes: Routes = [
{ {
path: AddonMessagesMainMenuHandlerService.PAGE_NAME, path: AddonMessagesMainMenuHandlerService.PAGE_NAME,
loadChildren: () => import('./messages-lazy.module').then(m => m.AddonMessagesLazyModule), loadChildren: () => import('./messages-lazy.module'),
}, },
]; ];
const preferencesRoutes: Routes = [ const preferencesRoutes: Routes = [
{ {
path: AddonMessagesSettingsHandlerService.PAGE_NAME, path: AddonMessagesSettingsHandlerService.PAGE_NAME,
loadChildren: () => import('./messages-settings-lazy.module').then(m => m.AddonMessagesSettingsLazyModule), loadChildren: () => import('./messages-settings-lazy.module'),
}, },
]; ];

View File

@ -15,7 +15,6 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { import {
AddonMessagesProvider,
AddonMessagesGetContactsWSResponse, AddonMessagesGetContactsWSResponse,
AddonMessagesSearchContactsContact, AddonMessagesSearchContactsContact,
AddonMessagesGetContactsContact, AddonMessagesGetContactsContact,
@ -29,6 +28,7 @@ import { CoreScreen } from '@services/screen';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { CoreKeyboard } from '@singletons/keyboard'; import { CoreKeyboard } from '@singletons/keyboard';
import { ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT } from '@addons/messages/constants';
/** /**
* Page that displays the list of contacts. * Page that displays the list of contacts.
@ -36,7 +36,7 @@ import { CoreKeyboard } from '@singletons/keyboard';
@Component({ @Component({
selector: 'addon-messages-contacts', selector: 'addon-messages-contacts',
templateUrl: 'contacts.html', templateUrl: 'contacts.html',
styleUrls: ['../../messages-common.scss'], styleUrl: '../../messages-common.scss',
}) })
export class AddonMessagesContacts35Page implements OnInit, OnDestroy { export class AddonMessagesContacts35Page implements OnInit, OnDestroy {
@ -73,7 +73,7 @@ export class AddonMessagesContacts35Page implements OnInit, OnDestroy {
// Refresh the list when a contact request is confirmed. // Refresh the list when a contact request is confirmed.
this.memberInfoObserver = CoreEvents.on( this.memberInfoObserver = CoreEvents.on(
AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
(data) => { (data) => {
if (data.contactRequestConfirmed) { if (data.contactRequestConfirmed) {
this.refreshData(); this.refreshData();

View File

@ -18,12 +18,12 @@ import { CoreSites } from '@services/sites';
import { import {
AddonMessages, AddonMessages,
AddonMessagesConversationMember, AddonMessagesConversationMember,
AddonMessagesProvider,
} from '../../services/messages'; } from '../../services/messages';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreScreen } from '@services/screen'; import { CoreScreen } from '@services/screen';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT, ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT } from '@addons/messages/constants';
/** /**
* Page that displays contacts and contact requests. * Page that displays contacts and contact requests.
@ -31,9 +31,7 @@ import { CoreSplitViewComponent } from '@components/split-view/split-view';
@Component({ @Component({
selector: 'page-addon-messages-contacts', selector: 'page-addon-messages-contacts',
templateUrl: 'contacts.html', templateUrl: 'contacts.html',
styleUrls: [ styleUrl: '../../messages-common.scss',
'../../messages-common.scss',
],
}) })
export class AddonMessagesContactsPage implements OnInit, OnDestroy { export class AddonMessagesContactsPage implements OnInit, OnDestroy {
@ -65,7 +63,7 @@ export class AddonMessagesContactsPage implements OnInit, OnDestroy {
// Update the contact requests badge. // Update the contact requests badge.
this.contactRequestsCountObserver = CoreEvents.on( this.contactRequestsCountObserver = CoreEvents.on(
AddonMessagesProvider.CONTACT_REQUESTS_COUNT_EVENT, ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT,
(data) => { (data) => {
this.requestsBadge = data.count > 0 ? String(data.count) : ''; this.requestsBadge = data.count > 0 ? String(data.count) : '';
}, },
@ -74,7 +72,7 @@ export class AddonMessagesContactsPage implements OnInit, OnDestroy {
// Update block status of a user. // Update block status of a user.
this.memberInfoObserver = CoreEvents.on( this.memberInfoObserver = CoreEvents.on(
AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
(data) => { (data) => {
if (data.userBlocked || data.userUnblocked) { if (data.userBlocked || data.userUnblocked) {
const user = this.confirmedContacts.find((user) => user.id == data.userId); const user = this.confirmedContacts.find((user) => user.id == data.userId);

View File

@ -18,20 +18,18 @@ import { AlertOptions } from '@ionic/core';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { import {
AddonMessagesProvider,
AddonMessagesConversationFormatted, AddonMessagesConversationFormatted,
AddonMessagesConversationMember, AddonMessagesConversationMember,
AddonMessagesGetMessagesMessage, AddonMessagesGetMessagesMessage,
AddonMessages, AddonMessages,
AddonMessagesConversationMessageFormatted, AddonMessagesConversationMessageFormatted,
AddonMessagesSendMessageResults, AddonMessagesSendMessageResults,
AddonMessagesUpdateConversationAction,
} from '../../services/messages'; } from '../../services/messages';
import { AddonMessagesOffline, AddonMessagesOfflineMessagesDBRecordFormatted } from '../../services/messages-offline'; import { AddonMessagesOffline, AddonMessagesOfflineMessagesDBRecordFormatted } from '../../services/messages-offline';
import { AddonMessagesSync, AddonMessagesSyncProvider } from '../../services/messages-sync'; import { AddonMessagesSync } from '../../services/messages-sync';
import { CoreUser } from '@features/user/services/user'; import { CoreUser } from '@features/user/services/user';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { CoreInfiniteLoadingComponent } from '@components/infinite-loading/infinite-loading'; import { CoreInfiniteLoadingComponent } from '@components/infinite-loading/infinite-loading';
import { Md5 } from 'ts-md5/dist/md5'; import { Md5 } from 'ts-md5/dist/md5';
@ -48,6 +46,18 @@ import { CoreText } from '@singletons/text';
import { CoreWait } from '@singletons/wait'; import { CoreWait } from '@singletons/wait';
import { CoreModals } from '@services/modals'; import { CoreModals } from '@services/modals';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import {
ADDON_MESSAGES_AUTO_SYNCED,
ADDON_MESSAGES_LIMIT_MESSAGES,
ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
ADDON_MESSAGES_NEW_MESSAGE_EVENT,
ADDON_MESSAGES_OPEN_CONVERSATION_EVENT,
ADDON_MESSAGES_POLL_INTERVAL,
ADDON_MESSAGES_READ_CHANGED_EVENT,
ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT,
AddonMessagesMessageConversationType,
AddonMessagesUpdateConversationAction,
} from '@addons/messages/constants';
/** /**
* Page that displays a message discussion page. * Page that displays a message discussion page.
@ -125,7 +135,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
this.logger = CoreLogger.getInstance('AddonMessagesDiscussionPage'); this.logger = CoreLogger.getInstance('AddonMessagesDiscussionPage');
// Refresh data if this discussion is synchronized automatically. // Refresh data if this discussion is synchronized automatically.
this.syncObserver = CoreEvents.on(AddonMessagesSyncProvider.AUTO_SYNCED, (data) => { this.syncObserver = CoreEvents.on(ADDON_MESSAGES_AUTO_SYNCED, (data) => {
if ((data.userId && data.userId == this.userId) || if ((data.userId && data.userId == this.userId) ||
(data.conversationId && data.conversationId == this.conversationId)) { (data.conversationId && data.conversationId == this.conversationId)) {
// Fetch messages. // Fetch messages.
@ -140,7 +150,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
// Refresh data if info of a mamber of the conversation have changed. // Refresh data if info of a mamber of the conversation have changed.
this.memberInfoObserver = CoreEvents.on( this.memberInfoObserver = CoreEvents.on(
AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
(data) => { (data) => {
if (data.userId && (this.members[data.userId] || this.otherMember && data.userId == this.otherMember.id)) { if (data.userId && (this.members[data.userId] || this.otherMember && data.userId == this.otherMember.id)) {
this.fetchData(); this.fetchData();
@ -595,13 +605,13 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
this.conversationId = this.conversation.id; this.conversationId = this.conversation.id;
this.title = this.conversation.name; this.title = this.conversation.name;
this.conversationImage = this.conversation.imageurl; this.conversationImage = this.conversation.imageurl;
this.isGroup = this.conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP; this.isGroup = this.conversation.type === AddonMessagesMessageConversationType.GROUP;
this.favouriteIcon = 'fas-star'; this.favouriteIcon = 'fas-star';
this.muteIcon = this.conversation.ismuted ? 'fas-bell' : 'fas-bell-slash'; this.muteIcon = this.conversation.ismuted ? 'fas-bell' : 'fas-bell-slash';
if (!this.isGroup) { if (!this.isGroup) {
this.userId = this.conversation.userid; this.userId = this.conversation.userid;
} }
this.isSelf = this.conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_SELF; this.isSelf = this.conversation.type === AddonMessagesMessageConversationType.SELF;
return true; return true;
} else { } else {
@ -645,7 +655,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
const messages: AddonMessagesConversationMessageFormatted[] = result.messages; const messages: AddonMessagesConversationMessageFormatted[] = result.messages;
if (pagesToLoad > 0 && result.canLoadMore) { if (pagesToLoad > 0 && result.canLoadMore) {
offset += AddonMessagesProvider.LIMIT_MESSAGES; offset += ADDON_MESSAGES_LIMIT_MESSAGES;
// Get more messages. // Get more messages.
const nextMessages = await this.getConversationMessages(pagesToLoad, offset); const nextMessages = await this.getConversationMessages(pagesToLoad, offset);
@ -764,7 +774,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
} }
if (readChanged) { if (readChanged) {
CoreEvents.trigger(AddonMessagesProvider.READ_CHANGED_EVENT, { CoreEvents.trigger(ADDON_MESSAGES_READ_CHANGED_EVENT, {
conversationId: this.conversationId, conversationId: this.conversationId,
userId: this.userId, userId: this.userId,
}, this.siteId); }, this.siteId);
@ -789,7 +799,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
if (trigger) { if (trigger) {
// Update discussions last message. // Update discussions last message.
CoreEvents.trigger(AddonMessagesProvider.NEW_MESSAGE_EVENT, { CoreEvents.trigger(ADDON_MESSAGES_NEW_MESSAGE_EVENT, {
conversationId: this.conversationId, conversationId: this.conversationId,
userId: this.userId, userId: this.userId,
message: this.lastMessage?.text, message: this.lastMessage?.text,
@ -887,7 +897,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
} }
await CoreWait.wait(400); await CoreWait.wait(400);
await CoreUtils.ignoreErrors(this.waitForFetch()); await CorePromiseUtils.ignoreErrors(this.waitForFetch());
} }
/** /**
@ -905,7 +915,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
this.fetchMessages().catch(() => { this.fetchMessages().catch(() => {
// Ignore errors. // Ignore errors.
}); });
}, AddonMessagesProvider.POLL_INTERVAL); }, ADDON_MESSAGES_POLL_INTERVAL);
} }
} }
@ -1265,7 +1275,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
if (splitViewLoaded) { if (splitViewLoaded) {
// Notify the left pane to load it, this way the right conversation will be highlighted. // Notify the left pane to load it, this way the right conversation will be highlighted.
CoreEvents.trigger( CoreEvents.trigger(
AddonMessagesProvider.OPEN_CONVERSATION_EVENT, ADDON_MESSAGES_OPEN_CONVERSATION_EVENT,
{ userId }, { userId },
this.siteId, this.siteId,
); );
@ -1300,7 +1310,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
// Get the conversation data so it's cached. Don't block the user for this. // Get the conversation data so it's cached. Don't block the user for this.
AddonMessages.getConversation(this.conversation.id, undefined, true); AddonMessages.getConversation(this.conversation.id, undefined, true);
CoreEvents.trigger(AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, { CoreEvents.trigger(ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT, {
conversationId: this.conversation.id, conversationId: this.conversation.id,
action: AddonMessagesUpdateConversationAction.FAVOURITE, action: AddonMessagesUpdateConversationAction.FAVOURITE,
value: this.conversation.isfavourite, value: this.conversation.isfavourite,
@ -1332,7 +1342,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
// Get the conversation data so it's cached. Don't block the user for this. // Get the conversation data so it's cached. Don't block the user for this.
AddonMessages.getConversation(this.conversation.id, undefined, true); AddonMessages.getConversation(this.conversation.id, undefined, true);
CoreEvents.trigger(AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, { CoreEvents.trigger(ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT, {
conversationId: this.conversation.id, conversationId: this.conversation.id,
action: AddonMessagesUpdateConversationAction.MUTE, action: AddonMessagesUpdateConversationAction.MUTE,
value: this.conversation.ismuted, value: this.conversation.ismuted,
@ -1447,7 +1457,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
await AddonMessages.deleteConversation(this.conversation.id); await AddonMessages.deleteConversation(this.conversation.id);
CoreEvents.trigger( CoreEvents.trigger(
AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT,
{ {
conversationId: this.conversation.id, conversationId: this.conversation.id,
action: AddonMessagesUpdateConversationAction.DELETE, action: AddonMessagesUpdateConversationAction.DELETE,

View File

@ -19,10 +19,9 @@ import {
AddonMessages, AddonMessages,
AddonMessagesDiscussion, AddonMessagesDiscussion,
AddonMessagesMessageAreaContact, AddonMessagesMessageAreaContact,
AddonMessagesProvider,
} from '../../services/messages'; } from '../../services/messages';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { ActivatedRoute, Params } from '@angular/router'; import { ActivatedRoute, Params } from '@angular/router';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CorePushNotificationsDelegate } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsDelegate } from '@features/pushnotifications/services/push-delegate';
@ -33,6 +32,8 @@ import { CoreScreen } from '@services/screen';
import { CorePlatform } from '@services/platform'; import { CorePlatform } from '@services/platform';
import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { CoreKeyboard } from '@singletons/keyboard'; import { CoreKeyboard } from '@singletons/keyboard';
import { ADDON_MESSAGES_NEW_MESSAGE_EVENT, ADDON_MESSAGES_READ_CHANGED_EVENT } from '@addons/messages/constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Page that displays the list of discussions. * Page that displays the list of discussions.
@ -40,7 +41,7 @@ import { CoreKeyboard } from '@singletons/keyboard';
@Component({ @Component({
selector: 'addon-messages-discussions', selector: 'addon-messages-discussions',
templateUrl: 'discussions.html', templateUrl: 'discussions.html',
styleUrls: ['../../messages-common.scss'], styleUrl: '../../messages-common.scss',
}) })
export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy { export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
@ -75,7 +76,7 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
// Update discussions when new message is received. // Update discussions when new message is received.
this.newMessagesObserver = CoreEvents.on( this.newMessagesObserver = CoreEvents.on(
AddonMessagesProvider.NEW_MESSAGE_EVENT, ADDON_MESSAGES_NEW_MESSAGE_EVENT,
(data) => { (data) => {
if (data.userId && this.discussions) { if (data.userId && this.discussions) {
const discussion = this.discussions.find((disc) => disc.message?.user === data.userId); const discussion = this.discussions.find((disc) => disc.message?.user === data.userId);
@ -97,7 +98,7 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
// Update discussions when a message is read. // Update discussions when a message is read.
this.readChangedObserver = CoreEvents.on( this.readChangedObserver = CoreEvents.on(
AddonMessagesProvider.READ_CHANGED_EVENT, ADDON_MESSAGES_READ_CHANGED_EVENT,
(data) => { (data) => {
if (data.userId && this.discussions) { if (data.userId && this.discussions) {
const discussion = this.discussions.find((disc) => disc.message?.user === data.userId); const discussion = this.discussions.find((disc) => disc.message?.user === data.userId);
@ -170,7 +171,7 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
promises.push(AddonMessages.invalidateUnreadConversationCounts(this.siteId)); promises.push(AddonMessages.invalidateUnreadConversationCounts(this.siteId));
} }
await CoreUtils.allPromises(promises).finally(() => this.fetchData().finally(() => { await CorePromiseUtils.allPromises(promises).finally(() => this.fetchData().finally(() => {
if (refresher) { if (refresher) {
refresher?.complete(); refresher?.complete();
} }

View File

@ -17,12 +17,10 @@ import { AccordionGroupChangeEventDetail, IonAccordionGroup, IonContent } from '
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { import {
AddonMessagesProvider,
AddonMessagesConversationFormatted, AddonMessagesConversationFormatted,
AddonMessages, AddonMessages,
AddonMessagesNewMessagedEventData, AddonMessagesNewMessagedEventData,
AddonMessagesUnreadConversationCountsEventData, AddonMessagesUnreadConversationCountsEventData,
AddonMessagesUpdateConversationAction,
} from '../../services/messages'; } from '../../services/messages';
import { import {
AddonMessagesOffline, AddonMessagesOffline,
@ -35,11 +33,22 @@ import { Translate } from '@singletons';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { ActivatedRoute, Params } from '@angular/router'; import { ActivatedRoute, Params } from '@angular/router';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreScreen } from '@services/screen'; import { CoreScreen } from '@services/screen';
import { CorePlatform } from '@services/platform'; import { CorePlatform } from '@services/platform';
import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreSplitViewComponent } from '@components/split-view/split-view';
import {
ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT,
ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
ADDON_MESSAGES_NEW_MESSAGE_EVENT,
ADDON_MESSAGES_OPEN_CONVERSATION_EVENT,
ADDON_MESSAGES_READ_CHANGED_EVENT,
ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT,
ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT,
AddonMessagesMessageConversationType,
AddonMessagesUpdateConversationAction,
} from '@addons/messages/constants';
const enum AddonMessagesGroupConversationOptionNames { const enum AddonMessagesGroupConversationOptionNames {
FAVOURITES = 'favourites', FAVOURITES = 'favourites',
@ -53,7 +62,7 @@ const enum AddonMessagesGroupConversationOptionNames {
@Component({ @Component({
selector: 'page-addon-messages-group-conversations', selector: 'page-addon-messages-group-conversations',
templateUrl: 'group-conversations.html', templateUrl: 'group-conversations.html',
styleUrls: ['../../messages-common.scss'], styleUrl: '../../messages-common.scss',
}) })
export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
@ -82,7 +91,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
optionName: AddonMessagesGroupConversationOptionNames.GROUP, optionName: AddonMessagesGroupConversationOptionNames.GROUP,
titleString: 'addon.messages.groupconversations', titleString: 'addon.messages.groupconversations',
emptyString: 'addon.messages.nogroupconversations', emptyString: 'addon.messages.nogroupconversations',
type: AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP, type: AddonMessagesMessageConversationType.GROUP,
favourites: false, favourites: false,
count: 0, count: 0,
unread: 0, unread: 0,
@ -92,7 +101,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
optionName: AddonMessagesGroupConversationOptionNames.INDIVIDUAL, optionName: AddonMessagesGroupConversationOptionNames.INDIVIDUAL,
titleString: 'addon.messages.individualconversations', titleString: 'addon.messages.individualconversations',
emptyString: 'addon.messages.noindividualconversations', emptyString: 'addon.messages.noindividualconversations',
type: AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, type: AddonMessagesMessageConversationType.INDIVIDUAL,
favourites: false, favourites: false,
count: 0, count: 0,
unread: 0, unread: 0,
@ -100,7 +109,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
}, },
]; ];
typeGroup = AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP; typeGroup = AddonMessagesMessageConversationType.GROUP;
protected siteId: string; protected siteId: string;
protected currentUserId: number; protected currentUserId: number;
@ -124,7 +133,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
// Update conversations when new message is received. // Update conversations when new message is received.
this.newMessagesObserver = CoreEvents.on( this.newMessagesObserver = CoreEvents.on(
AddonMessagesProvider.NEW_MESSAGE_EVENT, ADDON_MESSAGES_NEW_MESSAGE_EVENT,
(data) => { (data) => {
// Check if the new message belongs to the option that is currently expanded. // Check if the new message belongs to the option that is currently expanded.
const expandedOption = this.getExpandedOption(); const expandedOption = this.getExpandedOption();
@ -163,7 +172,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
conversation.lastmessagedate = data.timecreated / 1000; conversation.lastmessagedate = data.timecreated / 1000;
if (data.userFrom) { if (data.userFrom) {
conversation.sentfromcurrentuser = data.userFrom.id === this.currentUserId; conversation.sentfromcurrentuser = data.userFrom.id === this.currentUserId;
if (conversation.type === AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP) { if (conversation.type === AddonMessagesMessageConversationType.GROUP) {
conversation.members[0] = data.userFrom; conversation.members[0] = data.userFrom;
} }
} }
@ -183,7 +192,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
); );
// Update conversations when a message is read. // Update conversations when a message is read.
this.readChangedObserver = CoreEvents.on(AddonMessagesProvider.READ_CHANGED_EVENT, (data) => { this.readChangedObserver = CoreEvents.on(ADDON_MESSAGES_READ_CHANGED_EVENT, (data) => {
if (data.conversationId) { if (data.conversationId) {
const conversation = this.findConversation(data.conversationId); const conversation = this.findConversation(data.conversationId);
@ -200,7 +209,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
// Load a discussion if we receive an event to do so. // Load a discussion if we receive an event to do so.
this.openConversationObserver = CoreEvents.on( this.openConversationObserver = CoreEvents.on(
AddonMessagesProvider.OPEN_CONVERSATION_EVENT, ADDON_MESSAGES_OPEN_CONVERSATION_EVENT,
(data) => { (data) => {
if (data.conversationId || data.userId) { if (data.conversationId || data.userId) {
this.gotoConversation(data.conversationId, data.userId); this.gotoConversation(data.conversationId, data.userId);
@ -222,7 +231,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
// Update conversations if we receive an event to do so. // Update conversations if we receive an event to do so.
this.updateConversationListObserver = CoreEvents.on( this.updateConversationListObserver = CoreEvents.on(
AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT,
(data) => { (data) => {
if (data?.action === AddonMessagesUpdateConversationAction.MUTE) { if (data?.action === AddonMessagesUpdateConversationAction.MUTE) {
// If the conversation is displayed, change its muted value. // If the conversation is displayed, change its muted value.
@ -256,7 +265,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
// Update unread conversation counts. // Update unread conversation counts.
this.cronObserver = CoreEvents.on( this.cronObserver = CoreEvents.on(
AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT, ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT,
(data) => { (data) => {
this.setCounts(data, 'unread'); this.setCounts(data, 'unread');
}, },
@ -265,7 +274,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
// Update the contact requests badge. // Update the contact requests badge.
this.contactRequestsCountObserver = CoreEvents.on( this.contactRequestsCountObserver = CoreEvents.on(
AddonMessagesProvider.CONTACT_REQUESTS_COUNT_EVENT, ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT,
(data) => { (data) => {
this.contactRequestsCount = data.count; this.contactRequestsCount = data.count;
}, },
@ -274,7 +283,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
// Update block status of a user. // Update block status of a user.
this.memberInfoObserver = CoreEvents.on( this.memberInfoObserver = CoreEvents.on(
AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
(data) => { (data) => {
if (!data.userBlocked && !data.userUnblocked) { if (!data.userBlocked && !data.userUnblocked) {
// The block status has not changed, ignore. // The block status has not changed, ignore.
@ -638,7 +647,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
// Conversation not found, it could be an old one or the message could belong to another option. // Conversation not found, it could be an old one or the message could belong to another option.
conversation = { conversation = {
id: message.conversationid, id: message.conversationid,
type: message.conversation?.type || AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, type: message.conversation?.type || AddonMessagesMessageConversationType.INDIVIDUAL,
membercount: message.conversation?.membercount || 0, membercount: message.conversation?.membercount || 0,
ismuted: message.conversation?.ismuted || false, ismuted: message.conversation?.ismuted || false,
isfavourite: message.conversation?.isfavourite || false, isfavourite: message.conversation?.isfavourite || false,
@ -657,7 +666,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
this.addOfflineConversation(conversation, option); this.addOfflineConversation(conversation, option);
} }
} }
} else if (option.type === AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) { } else if (option.type === AddonMessagesMessageConversationType.INDIVIDUAL) {
// It's a new conversation. Check if we already created it (there is more than one message for the same user). // It's a new conversation. Check if we already created it (there is more than one message for the same user).
const conversation = this.findConversation(undefined, message.touserid, option); const conversation = this.findConversation(undefined, message.touserid, option);
@ -675,7 +684,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
}).then((user) => { }).then((user) => {
const conversation: AddonMessagesConversationForList = { const conversation: AddonMessagesConversationForList = {
id: 0, id: 0,
type: AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, type: AddonMessagesMessageConversationType.INDIVIDUAL,
membercount: 0, // Faked data. membercount: 0, // Faked data.
ismuted: false, // Faked data. ismuted: false, // Faked data.
isfavourite: false, // Faked data. isfavourite: false, // Faked data.
@ -742,7 +751,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy {
return AddonMessagesGroupConversationOptionNames.FAVOURITES; return AddonMessagesGroupConversationOptionNames.FAVOURITES;
} }
if (conversation.type === AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP) { if (conversation.type === AddonMessagesMessageConversationType.GROUP) {
return AddonMessagesGroupConversationOptionNames.GROUP; return AddonMessagesGroupConversationOptionNames.GROUP;
} }

View File

@ -16,7 +16,6 @@ import { Component, OnDestroy, ViewChild } from '@angular/core';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { import {
AddonMessagesProvider,
AddonMessagesConversationMember, AddonMessagesConversationMember,
AddonMessagesMessageAreaContact, AddonMessagesMessageAreaContact,
AddonMessages, AddonMessages,
@ -26,6 +25,11 @@ import { CoreNavigator } from '@services/navigator';
import { CoreScreen } from '@services/screen'; import { CoreScreen } from '@services/screen';
import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { CoreKeyboard } from '@singletons/keyboard'; import { CoreKeyboard } from '@singletons/keyboard';
import {
ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
ADDON_MESSAGES_LIMIT_SEARCH,
ADDON_MESSAGES_LIMIT_INITIAL_USER_SEARCH,
} from '@addons/messages/constants';
/** /**
* Page for searching users. * Page for searching users.
@ -74,7 +78,7 @@ export class AddonMessagesSearchPage implements OnDestroy {
constructor() { constructor() {
// Update block status of a user. // Update block status of a user.
this.memberInfoObserver = CoreEvents.on( this.memberInfoObserver = CoreEvents.on(
AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
(data) => { (data) => {
if (!data.userBlocked && !data.userUnblocked) { if (!data.userBlocked && !data.userUnblocked) {
// The block status has not changed, ignore. // The block status has not changed, ignore.
@ -139,7 +143,7 @@ export class AddonMessagesSearchPage implements OnDestroy {
let canLoadMoreMessages = false; let canLoadMoreMessages = false;
if (!loadMore || loadMore == 'contacts' || loadMore == 'noncontacts') { if (!loadMore || loadMore == 'contacts' || loadMore == 'noncontacts') {
const limitNum = loadMore ? AddonMessagesProvider.LIMIT_SEARCH : AddonMessagesProvider.LIMIT_INITIAL_USER_SEARCH; const limitNum = loadMore ? ADDON_MESSAGES_LIMIT_SEARCH : ADDON_MESSAGES_LIMIT_INITIAL_USER_SEARCH;
let limitFrom = 0; let limitFrom = 0;
if (loadMore == 'contacts') { if (loadMore == 'contacts') {
limitFrom = this.contacts.results.length; limitFrom = this.contacts.results.length;

View File

@ -14,7 +14,7 @@
import { Component, OnDestroy, OnInit, signal } from '@angular/core'; import { Component, OnDestroy, OnInit, signal } from '@angular/core';
import { import {
AddonMessagesProvider, AddonMessagesMessagePreferences, AddonMessagesMessagePreferences,
AddonMessagesMessagePreferencesNotification, AddonMessagesMessagePreferencesNotification,
AddonMessagesMessagePreferencesNotificationProcessor, AddonMessagesMessagePreferencesNotificationProcessor,
AddonMessages, AddonMessages,
@ -29,6 +29,7 @@ import { AddonNotificationsPreferencesNotificationProcessorState } from '@addons
import { CorePlatform } from '@services/platform'; import { CorePlatform } from '@services/platform';
import { CoreErrorHelper } from '@services/error-helper'; import { CoreErrorHelper } from '@services/error-helper';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import { ADDON_MESSAGES_NOTIFICATION_PREFERENCES_KEY, AddonMessagesMessagePrivacy } from '@addons/messages/constants';
/** /**
* Page that displays the messages settings page. * Page that displays the messages settings page.
@ -46,9 +47,9 @@ export class AddonMessagesSettingsPage implements OnInit, OnDestroy {
contactablePrivacy?: number | boolean; contactablePrivacy?: number | boolean;
advancedContactable = false; // Whether the site supports "advanced" contactable privacy. advancedContactable = false; // Whether the site supports "advanced" contactable privacy.
allowSiteMessaging = false; allowSiteMessaging = false;
onlyContactsValue = AddonMessagesProvider.MESSAGE_PRIVACY_ONLYCONTACTS; onlyContactsValue = AddonMessagesMessagePrivacy.ONLYCONTACTS;
courseMemberValue = AddonMessagesProvider.MESSAGE_PRIVACY_COURSEMEMBER; courseMemberValue = AddonMessagesMessagePrivacy.COURSEMEMBER;
siteValue = AddonMessagesProvider.MESSAGE_PRIVACY_SITE; siteValue = AddonMessagesMessagePrivacy.SITE;
groupMessagingEnabled = false; groupMessagingEnabled = false;
sendOnEnter = false; sendOnEnter = false;
warningMessage = signal<string | undefined>(undefined); warningMessage = signal<string | undefined>(undefined);
@ -91,7 +92,7 @@ export class AddonMessagesSettingsPage implements OnInit, OnDestroy {
for (const component of preferences.components) { for (const component of preferences.components) {
// Only display get the notification preferences. // Only display get the notification preferences.
component.notifications = component.notifications.filter((notification) => component.notifications = component.notifications.filter((notification) =>
notification.preferencekey == AddonMessagesProvider.NOTIFICATION_PREFERENCES_KEY); notification.preferencekey === ADDON_MESSAGES_NOTIFICATION_PREFERENCES_KEY);
if (this.loggedInOffLegacyMode) { if (this.loggedInOffLegacyMode) {
// Load enabled from loggedin / loggedoff values. // Load enabled from loggedin / loggedoff values.

View File

@ -14,20 +14,23 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import {
AddonMessagesProvider,
AddonMessages, AddonMessages,
} from '../messages'; } from '../messages';
import { CoreMainMenuHandler, CoreMainMenuHandlerToDisplay } from '@features/mainmenu/services/mainmenu-delegate'; import { CoreMainMenuHandler, CoreMainMenuHandlerToDisplay } from '@features/mainmenu/services/mainmenu-delegate';
import { CoreCronHandler } from '@services/cron'; import { CoreCronHandler } from '@services/cron';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { import {
CorePushNotificationsNotificationBasicData, CorePushNotificationsNotificationBasicData,
} from '@features/pushnotifications/services/pushnotifications'; } from '@features/pushnotifications/services/pushnotifications';
import { CorePushNotificationsDelegate } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsDelegate } from '@features/pushnotifications/services/push-delegate';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreMainMenuProvider } from '@features/mainmenu/services/mainmenu'; import {
ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT,
ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT,
} from '@addons/messages/constants';
import { MAIN_MENU_HANDLER_BADGE_UPDATED_EVENT } from '@features/mainmenu/constants';
/** /**
* Handler to inject an option into main menu. * Handler to inject an option into main menu.
@ -58,14 +61,14 @@ export class AddonMessagesMainMenuHandlerService implements CoreMainMenuHandler,
constructor() { constructor() {
CoreEvents.on(AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT, (data) => { CoreEvents.on(ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT, (data) => {
this.unreadCount = data.favourites + data.individual + data.group + data.self; this.unreadCount = data.favourites + data.individual + data.group + data.self;
this.orMore = !!data.orMore; this.orMore = !!data.orMore;
data.siteId && this.updateBadge(data.siteId); data.siteId && this.updateBadge(data.siteId);
}); });
CoreEvents.on(AddonMessagesProvider.CONTACT_REQUESTS_COUNT_EVENT, (data) => { CoreEvents.on(ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT, (data) => {
this.contactRequestsCount = data.count; this.contactRequestsCount = data.count;
data.siteId && this.updateBadge(data.siteId); data.siteId && this.updateBadge(data.siteId);
@ -174,7 +177,7 @@ export class AddonMessagesMainMenuHandlerService implements CoreMainMenuHandler,
// Update push notifications badge. // Update push notifications badge.
CoreEvents.trigger( CoreEvents.trigger(
CoreMainMenuProvider.MAIN_MENU_HANDLER_BADGE_UPDATED, MAIN_MENU_HANDLER_BADGE_UPDATED_EVENT,
{ {
handler: AddonMessagesMainMenuHandlerService.name, handler: AddonMessagesMainMenuHandlerService.name,
value: totalCount, value: totalCount,

View File

@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonMessages } from '../messages'; import { AddonMessages } from '../messages';
import { AddonMessagesMainMenuHandlerService } from './mainmenu'; import { AddonMessagesMainMenuHandlerService } from './mainmenu';

View File

@ -18,12 +18,11 @@ import {
AddonMessagesOffline, AddonMessagesOfflineAnyMessagesFormatted, AddonMessagesOffline, AddonMessagesOfflineAnyMessagesFormatted,
} from './messages-offline'; } from './messages-offline';
import { import {
AddonMessagesProvider,
AddonMessages, AddonMessages,
AddonMessagesGetMessagesWSParams, AddonMessagesGetMessagesWSParams,
} from './messages'; } from './messages';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreUtils } from '@services/utils/utils'; import { CoreWSError } from '@classes/errors/wserror';
import { makeSingleton, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreNetwork } from '@services/network'; import { CoreNetwork } from '@services/network';
@ -33,6 +32,20 @@ import { CoreError } from '@classes/errors/error';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreWait } from '@singletons/wait'; import { CoreWait } from '@singletons/wait';
import { CoreErrorHelper, CoreErrorObject } from '@services/error-helper'; import { CoreErrorHelper, CoreErrorObject } from '@services/error-helper';
import { ADDON_MESSAGES_AUTO_SYNCED, ADDON_MESSAGES_LIMIT_MESSAGES } from '../constants';
declare module '@singletons/events' {
/**
* Augment CoreEventsData interface with events specific to this service.
*
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
*/
export interface CoreEventsData {
[ADDON_MESSAGES_AUTO_SYNCED]: AddonMessagesSyncEvents;
}
}
/** /**
* Service to sync messages. * Service to sync messages.
@ -40,8 +53,6 @@ import { CoreErrorHelper, CoreErrorObject } from '@services/error-helper';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AddonMessagesSyncProvider extends CoreSyncBaseProvider<AddonMessagesSyncEvents> { export class AddonMessagesSyncProvider extends CoreSyncBaseProvider<AddonMessagesSyncEvents> {
static readonly AUTO_SYNCED = 'addon_messages_autom_synced';
constructor() { constructor() {
super('AddonMessagesSync'); super('AddonMessagesSync');
} }
@ -113,7 +124,7 @@ export class AddonMessagesSyncProvider extends CoreSyncBaseProvider<AddonMessage
} }
// Sync successful, send event. // Sync successful, send event.
CoreEvents.trigger(AddonMessagesSyncProvider.AUTO_SYNCED, result, siteId); CoreEvents.trigger(ADDON_MESSAGES_AUTO_SYNCED, result, siteId);
return; return;
})); }));
@ -126,7 +137,7 @@ export class AddonMessagesSyncProvider extends CoreSyncBaseProvider<AddonMessage
} }
// Sync successful, send event. // Sync successful, send event.
CoreEvents.trigger(AddonMessagesSyncProvider.AUTO_SYNCED, result, siteId); CoreEvents.trigger(ADDON_MESSAGES_AUTO_SYNCED, result, siteId);
return; return;
})); }));
@ -227,7 +238,7 @@ export class AddonMessagesSyncProvider extends CoreSyncBaseProvider<AddonMessage
await AddonMessages.sendMessageOnline(userId, text, siteId); await AddonMessages.sendMessageOnline(userId, text, siteId);
} }
} catch (error) { } catch (error) {
if (!CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
// Error sending, stop execution. // Error sending, stop execution.
if (CoreNetwork.isOnline()) { if (CoreNetwork.isOnline()) {
// App is online, unmark deviceoffline if marked. // App is online, unmark deviceoffline if marked.
@ -305,7 +316,7 @@ export class AddonMessagesSyncProvider extends CoreSyncBaseProvider<AddonMessage
const params: AddonMessagesGetMessagesWSParams = { const params: AddonMessagesGetMessagesWSParams = {
useridto: userId, useridto: userId,
useridfrom: siteCurrentUserId, useridfrom: siteCurrentUserId,
limitnum: AddonMessagesProvider.LIMIT_MESSAGES, limitnum: ADDON_MESSAGES_LIMIT_MESSAGES,
}; };
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: AddonMessages.getCacheKeyForDiscussion(userId), cacheKey: AddonMessages.getCacheKeyForDiscussion(userId),

View File

@ -23,17 +23,35 @@ import {
AddonMessagesOfflineConversationMessagesDBRecordFormatted, AddonMessagesOfflineConversationMessagesDBRecordFormatted,
AddonMessagesOfflineMessagesDBRecordFormatted, AddonMessagesOfflineMessagesDBRecordFormatted,
} from './messages-offline'; } from './messages-offline';
import { CoreUtils } from '@services/utils/utils';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreSite } from '@classes/sites/site'; import { CoreSite } from '@classes/sites/site';
import { CoreWSExternalWarning } from '@services/ws'; import { CoreWSExternalWarning } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { AddonMessagesSyncEvents, AddonMessagesSyncProvider } from './messages-sync';
import { CoreWSError } from '@classes/errors/wserror'; import { CoreWSError } from '@classes/errors/wserror';
import { AddonNotificationsPreferencesNotificationProcessorState } from '@addons/notifications/services/notifications'; import { AddonNotificationsPreferencesNotificationProcessorState } from '@addons/notifications/services/notifications';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { CoreCacheUpdateFrequency } from '@/core/constants';
import {
ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT,
ADDON_MESSAGES_LIMIT_CONTACTS,
ADDON_MESSAGES_LIMIT_INITIAL_USER_SEARCH,
ADDON_MESSAGES_LIMIT_MESSAGES,
ADDON_MESSAGES_LIMIT_SEARCH,
ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT,
ADDON_MESSAGES_NEW_MESSAGE_EVENT,
ADDON_MESSAGES_OPEN_CONVERSATION_EVENT,
ADDON_MESSAGES_POLL_INTERVAL,
ADDON_MESSAGES_PUSH_SIMULATION_COMPONENT,
ADDON_MESSAGES_READ_CHANGED_EVENT,
ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT,
ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT,
AddonMessagesMessageConversationType,
AddonMessagesMessagePrivacy,
AddonMessagesUpdateConversationAction,
} from '../constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
declare module '@singletons/events' { declare module '@singletons/events' {
@ -43,24 +61,17 @@ declare module '@singletons/events' {
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation * @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
*/ */
export interface CoreEventsData { export interface CoreEventsData {
[AddonMessagesProvider.NEW_MESSAGE_EVENT]: AddonMessagesNewMessagedEventData; [ADDON_MESSAGES_NEW_MESSAGE_EVENT]: AddonMessagesNewMessagedEventData;
[AddonMessagesProvider.READ_CHANGED_EVENT]: AddonMessagesReadChangedEventData; [ADDON_MESSAGES_READ_CHANGED_EVENT]: AddonMessagesReadChangedEventData;
[AddonMessagesProvider.OPEN_CONVERSATION_EVENT]: AddonMessagesOpenConversationEventData; [ADDON_MESSAGES_OPEN_CONVERSATION_EVENT]: AddonMessagesOpenConversationEventData;
[AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT]: AddonMessagesUpdateConversationListEventData; [ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT]: AddonMessagesUpdateConversationListEventData;
[AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT]: AddonMessagesMemberInfoChangedEventData; [ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT]: AddonMessagesMemberInfoChangedEventData;
[AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT]: AddonMessagesUnreadConversationCountsEventData; [ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT]: AddonMessagesUnreadConversationCountsEventData;
[AddonMessagesProvider.CONTACT_REQUESTS_COUNT_EVENT]: AddonMessagesContactRequestCountEventData; [ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT]: AddonMessagesContactRequestCountEventData;
[AddonMessagesSyncProvider.AUTO_SYNCED]: AddonMessagesSyncEvents;
} }
} }
export const enum AddonMessagesUpdateConversationAction {
MUTE = 'mute',
FAVOURITE = 'favourite',
DELETE = 'delete',
}
/** /**
* Service to handle messages. * Service to handle messages.
*/ */
@ -69,27 +80,87 @@ export class AddonMessagesProvider {
protected static readonly ROOT_CACHE_KEY = 'mmaMessages:'; protected static readonly ROOT_CACHE_KEY = 'mmaMessages:';
static readonly NEW_MESSAGE_EVENT = 'addon_messages_new_message_event'; /**
static readonly READ_CHANGED_EVENT = 'addon_messages_read_changed_event'; * @deprecated since 5.0. Use ADDON_MESSAGES_NEW_MESSAGE_EVENT instead.
static readonly OPEN_CONVERSATION_EVENT = 'addon_messages_open_conversation_event'; // Notify a conversation should be opened. */
static readonly UPDATE_CONVERSATION_LIST_EVENT = 'addon_messages_update_conversation_list_event'; static readonly NEW_MESSAGE_EVENT = ADDON_MESSAGES_NEW_MESSAGE_EVENT;
static readonly MEMBER_INFO_CHANGED_EVENT = 'addon_messages_member_changed_event'; /**
static readonly UNREAD_CONVERSATION_COUNTS_EVENT = 'addon_messages_unread_conversation_counts_event'; * @deprecated since 5.0. Use ADDON_MESSAGES_READ_CHANGED_EVENT instead.
static readonly CONTACT_REQUESTS_COUNT_EVENT = 'addon_messages_contact_requests_count_event'; */
static readonly POLL_INTERVAL = 10000; static readonly READ_CHANGED_EVENT = ADDON_MESSAGES_READ_CHANGED_EVENT;
static readonly PUSH_SIMULATION_COMPONENT = 'AddonMessagesPushSimulation'; /**
* @deprecated since 5.0. Use ADDON_MESSAGES_OPEN_CONVERSATION_EVENT instead.
*/
static readonly OPEN_CONVERSATION_EVENT = ADDON_MESSAGES_OPEN_CONVERSATION_EVENT;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT instead.
*/
static readonly UPDATE_CONVERSATION_LIST_EVENT = ADDON_MESSAGES_UPDATE_CONVERSATION_LIST_EVENT;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT instead.
*/
static readonly MEMBER_INFO_CHANGED_EVENT = ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT instead.
*/
static readonly UNREAD_CONVERSATION_COUNTS_EVENT = ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT instead.
*/
static readonly CONTACT_REQUESTS_COUNT_EVENT = ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_POLL_INTERVAL instead.
*/
static readonly POLL_INTERVAL = ADDON_MESSAGES_POLL_INTERVAL;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_PUSH_SIMULATION_COMPONENT instead.
*/
static readonly PUSH_SIMULATION_COMPONENT = ADDON_MESSAGES_PUSH_SIMULATION_COMPONENT;
static readonly MESSAGE_PRIVACY_COURSEMEMBER = 0; // Privacy setting for being messaged by anyone within courses user is member. /**
static readonly MESSAGE_PRIVACY_ONLYCONTACTS = 1; // Privacy setting for being messaged only by contacts. * @deprecated since 5.0. Use AddonMessagesMessagePrivacy.COURSEMEMBER instead.
static readonly MESSAGE_PRIVACY_SITE = 2; // Privacy setting for being messaged by anyone on the site. */
static readonly MESSAGE_CONVERSATION_TYPE_INDIVIDUAL = 1; // An individual conversation. static readonly MESSAGE_PRIVACY_COURSEMEMBER = AddonMessagesMessagePrivacy.COURSEMEMBER;
static readonly MESSAGE_CONVERSATION_TYPE_GROUP = 2; // A group conversation. /**
static readonly MESSAGE_CONVERSATION_TYPE_SELF = 3; // A self conversation. * @deprecated since 5.0. Use AddonMessagesMessagePrivacy.ONLYCONTACTS instead.
static readonly LIMIT_CONTACTS = 50; */
static readonly LIMIT_MESSAGES = 50; static readonly MESSAGE_PRIVACY_ONLYCONTACTS = AddonMessagesMessagePrivacy.ONLYCONTACTS;
static readonly LIMIT_INITIAL_USER_SEARCH = 3; /**
static readonly LIMIT_SEARCH = 50; * @deprecated since 5.0. Use AddonMessagesMessagePrivacy.SITE instead.
*/
static readonly MESSAGE_PRIVACY_SITE = AddonMessagesMessagePrivacy.SITE;
/**
* @deprecated since 5.0. Use AddonMessagesMessageConversationType.INDIVIDUAL instead.
*/
static readonly MESSAGE_CONVERSATION_TYPE_INDIVIDUAL = AddonMessagesMessageConversationType.INDIVIDUAL;
/**
* @deprecated since 5.0. Use AddonMessagesMessageConversationType.GROUP instead.
*/
static readonly MESSAGE_CONVERSATION_TYPE_GROUP = AddonMessagesMessageConversationType.GROUP;
/**
* @deprecated since 5.0. Use AddonMessagesMessageConversationType.SELF instead.
*/
static readonly MESSAGE_CONVERSATION_TYPE_SELF = AddonMessagesMessageConversationType.SELF;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_LIMIT_CONTACTS instead.
*/
static readonly LIMIT_CONTACTS = ADDON_MESSAGES_LIMIT_CONTACTS;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_LIMIT_MESSAGES instead.
*/
static readonly LIMIT_MESSAGES = ADDON_MESSAGES_LIMIT_MESSAGES;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_LIMIT_INITIAL_USER_SEARCH instead.
*/
static readonly LIMIT_INITIAL_USER_SEARCH = ADDON_MESSAGES_LIMIT_INITIAL_USER_SEARCH;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_LIMIT_SEARCH instead.
*/
static readonly LIMIT_SEARCH = ADDON_MESSAGES_LIMIT_SEARCH;
/**
* @deprecated since 5.0. Use ADDON_MESSAGES_NEW_MESSAGE_EVENT instead.
*/
static readonly NOTIFICATION_PREFERENCES_KEY = 'message_provider_moodle_instantmessage'; static readonly NOTIFICATION_PREFERENCES_KEY = 'message_provider_moodle_instantmessage';
protected logger: CoreLogger; protected logger: CoreLogger;
@ -147,7 +218,7 @@ export class AddonMessagesProvider {
} finally { } finally {
const data: AddonMessagesMemberInfoChangedEventData = { userId, userBlocked: true }; const data: AddonMessagesMemberInfoChangedEventData = { userId, userBlocked: true };
CoreEvents.trigger(AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, data, site.id); CoreEvents.trigger(ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT, data, site.id);
} }
} }
@ -169,14 +240,14 @@ export class AddonMessagesProvider {
await site.write('core_message_confirm_contact_request', params); await site.write('core_message_confirm_contact_request', params);
await CoreUtils.allPromises([ await CorePromiseUtils.allPromises([
this.invalidateAllMemberInfo(userId, site), this.invalidateAllMemberInfo(userId, site),
this.invalidateContactsCache(site.id), this.invalidateContactsCache(site.id),
this.invalidateUserContacts(site.id), this.invalidateUserContacts(site.id),
this.refreshContactRequestsCount(site.id), this.refreshContactRequestsCount(site.id),
]).finally(() => { ]).finally(() => {
const data: AddonMessagesMemberInfoChangedEventData = { userId, contactRequestConfirmed: true }; const data: AddonMessagesMemberInfoChangedEventData = { userId, contactRequestConfirmed: true };
CoreEvents.trigger(AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, data, site.id); CoreEvents.trigger(ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT, data, site.id);
}); });
} }
@ -212,7 +283,7 @@ export class AddonMessagesProvider {
await this.invalidateAllMemberInfo(userId, site).finally(() => { await this.invalidateAllMemberInfo(userId, site).finally(() => {
const data: AddonMessagesMemberInfoChangedEventData = { userId, contactRequestCreated: true }; const data: AddonMessagesMemberInfoChangedEventData = { userId, contactRequestCreated: true };
CoreEvents.trigger(AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, data, site.id); CoreEvents.trigger(ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT, data, site.id);
}); });
} }
@ -234,12 +305,12 @@ export class AddonMessagesProvider {
await site.write('core_message_decline_contact_request', params); await site.write('core_message_decline_contact_request', params);
await CoreUtils.allPromises([ await CorePromiseUtils.allPromises([
this.invalidateAllMemberInfo(userId, site), this.invalidateAllMemberInfo(userId, site),
this.refreshContactRequestsCount(site.id), this.refreshContactRequestsCount(site.id),
]).finally(() => { ]).finally(() => {
const data: AddonMessagesMemberInfoChangedEventData = { userId, contactRequestDeclined: true }; const data: AddonMessagesMemberInfoChangedEventData = { userId, contactRequestDeclined: true };
CoreEvents.trigger(AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, data, site.id); CoreEvents.trigger(ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT, data, site.id);
}); });
} }
@ -373,8 +444,8 @@ export class AddonMessagesProvider {
conversation.lastmessagedate = lastMessage ? lastMessage.timecreated : undefined; conversation.lastmessagedate = lastMessage ? lastMessage.timecreated : undefined;
conversation.sentfromcurrentuser = lastMessage ? lastMessage.useridfrom == userId : undefined; conversation.sentfromcurrentuser = lastMessage ? lastMessage.useridfrom == userId : undefined;
if (conversation.type != AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP) { if (conversation.type != AddonMessagesMessageConversationType.GROUP) {
const isIndividual = conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL; const isIndividual = conversation.type == AddonMessagesMessageConversationType.INDIVIDUAL;
const otherUser = conversation.members.find((member) => const otherUser = conversation.members.find((member) =>
(isIndividual && member.id != userId) || (!isIndividual && member.id == userId)); (isIndividual && member.id != userId) || (!isIndividual && member.id == userId));
@ -628,7 +699,7 @@ export class AddonMessagesProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCacheKeyForBlockedContacts(userId), cacheKey: this.getCacheKeyForBlockedContacts(userId),
updateFrequency: CoreSite.FREQUENCY_OFTEN, updateFrequency: CoreCacheUpdateFrequency.OFTEN,
}; };
return site.read('core_message_get_blocked_users', params, preSets); return site.read('core_message_get_blocked_users', params, preSets);
@ -648,7 +719,7 @@ export class AddonMessagesProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCacheKeyForContacts(), cacheKey: this.getCacheKeyForContacts(),
updateFrequency: CoreSite.FREQUENCY_OFTEN, updateFrequency: CoreCacheUpdateFrequency.OFTEN,
}; };
const contacts = await site.read<AddonMessagesGetContactsWSResponse>('core_message_get_contacts', undefined, preSets); const contacts = await site.read<AddonMessagesGetContactsWSResponse>('core_message_get_contacts', undefined, preSets);
@ -679,14 +750,14 @@ export class AddonMessagesProvider {
* Get the list of user contacts. * Get the list of user contacts.
* *
* @param limitFrom Position of the first contact to fetch. * @param limitFrom Position of the first contact to fetch.
* @param limitNum Number of contacts to fetch. Default is AddonMessagesProvider.LIMIT_CONTACTS. * @param limitNum Number of contacts to fetch. Default is ADDON_MESSAGES_LIMIT_CONTACTS.
* @param siteId Site ID. If not defined, use current site. * @param siteId Site ID. If not defined, use current site.
* @returns Promise resolved with the list of user contacts. * @returns Promise resolved with the list of user contacts.
* @since 3.6 * @since 3.6
*/ */
async getUserContacts( async getUserContacts(
limitFrom: number = 0, limitFrom: number = 0,
limitNum: number = AddonMessagesProvider.LIMIT_CONTACTS, limitNum: number = ADDON_MESSAGES_LIMIT_CONTACTS,
siteId?: string, siteId?: string,
): Promise<{contacts: AddonMessagesConversationMember[]; canLoadMore: boolean}> { ): Promise<{contacts: AddonMessagesConversationMember[]; canLoadMore: boolean}> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
@ -699,7 +770,7 @@ export class AddonMessagesProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCacheKeyForUserContacts(), cacheKey: this.getCacheKeyForUserContacts(),
updateFrequency: CoreSite.FREQUENCY_OFTEN, updateFrequency: CoreCacheUpdateFrequency.OFTEN,
}; };
const contacts = await site.read<AddonMessagesGetUserContactsWSResponse>('core_message_get_user_contacts', params, preSets); const contacts = await site.read<AddonMessagesGetUserContactsWSResponse>('core_message_get_user_contacts', params, preSets);
@ -723,14 +794,14 @@ export class AddonMessagesProvider {
* Get the contact request sent to the current user. * Get the contact request sent to the current user.
* *
* @param limitFrom Position of the first contact request to fetch. * @param limitFrom Position of the first contact request to fetch.
* @param limitNum Number of contact requests to fetch. Default is AddonMessagesProvider.LIMIT_CONTACTS. * @param limitNum Number of contact requests to fetch. Default is ADDON_MESSAGES_LIMIT_CONTACTS.
* @param siteId Site ID. If not defined, use current site. * @param siteId Site ID. If not defined, use current site.
* @returns Promise resolved with the list of contact requests. * @returns Promise resolved with the list of contact requests.
* @since 3.6 * @since 3.6
*/ */
async getContactRequests( async getContactRequests(
limitFrom: number = 0, limitFrom: number = 0,
limitNum: number = AddonMessagesProvider.LIMIT_CONTACTS, limitNum: number = ADDON_MESSAGES_LIMIT_CONTACTS,
siteId?: string, siteId?: string,
): Promise<{requests: AddonMessagesConversationMember[]; canLoadMore: boolean}> { ): Promise<{requests: AddonMessagesConversationMember[]; canLoadMore: boolean}> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
@ -743,7 +814,7 @@ export class AddonMessagesProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCacheKeyForContactRequests(), cacheKey: this.getCacheKeyForContactRequests(),
updateFrequency: CoreSite.FREQUENCY_OFTEN, updateFrequency: CoreCacheUpdateFrequency.OFTEN,
}; };
const requests = await site.read<AddonMessagesGetContactRequestsWSResponse>( const requests = await site.read<AddonMessagesGetContactRequestsWSResponse>(
@ -791,7 +862,7 @@ export class AddonMessagesProvider {
}; };
// Notify the new count so all badges are updated. // Notify the new count so all badges are updated.
CoreEvents.trigger(AddonMessagesProvider.CONTACT_REQUESTS_COUNT_EVENT, data , site.id); CoreEvents.trigger(ADDON_MESSAGES_CONTACT_REQUESTS_COUNT_EVENT, data , site.id);
return data.count; return data.count;
@ -935,11 +1006,11 @@ export class AddonMessagesProvider {
): Promise<{members: AddonMessagesConversationMember[]; canLoadMore: boolean}> { ): Promise<{members: AddonMessagesConversationMember[]; canLoadMore: boolean}> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
userId = userId || site.getUserId(); userId = userId || site.getUserId();
limitTo = limitTo ?? AddonMessagesProvider.LIMIT_MESSAGES; limitTo = limitTo ?? ADDON_MESSAGES_LIMIT_MESSAGES;
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCacheKeyForConversationMembers(userId, conversationId), cacheKey: this.getCacheKeyForConversationMembers(userId, conversationId),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
const params: AddonMessagesGetConversationMembersWSParams = { const params: AddonMessagesGetConversationMembersWSParams = {
@ -983,7 +1054,7 @@ export class AddonMessagesProvider {
options.userId = options.userId || site.getUserId(); options.userId = options.userId || site.getUserId();
options.limitFrom = options.limitFrom || 0; options.limitFrom = options.limitFrom || 0;
options.limitTo = options.limitTo ?? AddonMessagesProvider.LIMIT_MESSAGES; options.limitTo = options.limitTo ?? ADDON_MESSAGES_LIMIT_MESSAGES;
options.timeFrom = options.timeFrom || 0; options.timeFrom = options.timeFrom || 0;
options.newestFirst = options.newestFirst ?? true; options.newestFirst = options.newestFirst ?? true;
@ -1076,7 +1147,7 @@ export class AddonMessagesProvider {
const params: AddonMessagesGetConversationsWSParams = { const params: AddonMessagesGetConversationsWSParams = {
userid: userId, userid: userId,
limitfrom: limitFrom, limitfrom: limitFrom,
limitnum: AddonMessagesProvider.LIMIT_MESSAGES + 1, limitnum: ADDON_MESSAGES_LIMIT_MESSAGES + 1,
}; };
if (forceCache) { if (forceCache) {
@ -1091,7 +1162,7 @@ export class AddonMessagesProvider {
if (favourites !== undefined && favourites != null) { if (favourites !== undefined && favourites != null) {
params.favourites = !!favourites; params.favourites = !!favourites;
} }
if (site.isVersionGreaterEqualThan('3.7') && type != AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP) { if (site.isVersionGreaterEqualThan('3.7') && type != AddonMessagesMessageConversationType.GROUP) {
// Add self conversation to the list. // Add self conversation to the list.
params.mergeself = true; params.mergeself = true;
} }
@ -1112,12 +1183,12 @@ export class AddonMessagesProvider {
// Format the conversations, adding some calculated fields. // Format the conversations, adding some calculated fields.
const conversations = response.conversations const conversations = response.conversations
.slice(0, AddonMessagesProvider.LIMIT_MESSAGES) .slice(0, ADDON_MESSAGES_LIMIT_MESSAGES)
.map((conversation) => this.formatConversation(conversation, userId!)); .map((conversation) => this.formatConversation(conversation, userId!));
return { return {
conversations, conversations,
canLoadMore: response.conversations.length > AddonMessagesProvider.LIMIT_MESSAGES, canLoadMore: response.conversations.length > ADDON_MESSAGES_LIMIT_MESSAGES,
}; };
} }
@ -1144,9 +1215,9 @@ export class AddonMessagesProvider {
const counts = { const counts = {
favourites: result.favourites, favourites: result.favourites,
individual: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL], individual: result.types[AddonMessagesMessageConversationType.INDIVIDUAL],
group: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP], group: result.types[AddonMessagesMessageConversationType.GROUP],
self: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_SELF] || 0, self: result.types[AddonMessagesMessageConversationType.SELF] || 0,
}; };
return counts; return counts;
@ -1189,7 +1260,7 @@ export class AddonMessagesProvider {
const params: AddonMessagesGetMessagesWSParams = { const params: AddonMessagesGetMessagesWSParams = {
useridto: site.getUserId(), useridto: site.getUserId(),
useridfrom: userId, useridfrom: userId,
limitnum: AddonMessagesProvider.LIMIT_MESSAGES, limitnum: ADDON_MESSAGES_LIMIT_MESSAGES,
}; };
if (lfReceivedUnread > 0 || lfReceivedRead > 0 || lfSentUnread > 0 || lfSentRead > 0) { if (lfReceivedUnread > 0 || lfReceivedRead > 0 || lfSentUnread > 0 || lfSentRead > 0) {
@ -1212,13 +1283,13 @@ export class AddonMessagesProvider {
result.messages = result.messages.concat(sent); result.messages = result.messages.concat(sent);
const hasSent = sent.length > 0; const hasSent = sent.length > 0;
if (result.messages.length > AddonMessagesProvider.LIMIT_MESSAGES) { if (result.messages.length > ADDON_MESSAGES_LIMIT_MESSAGES) {
// Sort messages and get the more recent ones. // Sort messages and get the more recent ones.
result.canLoadMore = true; result.canLoadMore = true;
result.messages = this.sortMessages(result['messages']); result.messages = this.sortMessages(result['messages']);
result.messages = result.messages.slice(-AddonMessagesProvider.LIMIT_MESSAGES); result.messages = result.messages.slice(-ADDON_MESSAGES_LIMIT_MESSAGES);
} else { } else {
result.canLoadMore = result.messages.length == AddonMessagesProvider.LIMIT_MESSAGES && (!hasReceived || !hasSent); result.canLoadMore = result.messages.length == ADDON_MESSAGES_LIMIT_MESSAGES && (!hasReceived || !hasSent);
} }
if (excludePending) { if (excludePending) {
@ -1289,7 +1360,7 @@ export class AddonMessagesProvider {
const params: AddonMessagesGetMessagesWSParams = { const params: AddonMessagesGetMessagesWSParams = {
useridto: currentUserId, useridto: currentUserId,
useridfrom: 0, useridfrom: 0,
limitnum: AddonMessagesProvider.LIMIT_MESSAGES, limitnum: ADDON_MESSAGES_LIMIT_MESSAGES,
}; };
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
@ -1371,7 +1442,7 @@ export class AddonMessagesProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getCacheKeyForMemberInfo(userId, otherUserId), cacheKey: this.getCacheKeyForMemberInfo(userId, otherUserId),
updateFrequency: CoreSite.FREQUENCY_OFTEN, updateFrequency: CoreCacheUpdateFrequency.OFTEN,
}; };
const params: AddonMessagesGetMemberInfoWSParams = { const params: AddonMessagesGetMemberInfoWSParams = {
referenceuserid: userId, referenceuserid: userId,
@ -1410,7 +1481,7 @@ export class AddonMessagesProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getMessagePreferencesCacheKey(), cacheKey: this.getMessagePreferencesCacheKey(),
updateFrequency: CoreSite.FREQUENCY_SOMETIMES, updateFrequency: CoreCacheUpdateFrequency.SOMETIMES,
}; };
const data = await site.read<AddonMessagesGetUserMessagePreferencesWSResponse>( const data = await site.read<AddonMessagesGetUserMessagePreferencesWSResponse>(
@ -1572,9 +1643,9 @@ export class AddonMessagesProvider {
counts = { counts = {
favourites: result.favourites, favourites: result.favourites,
individual: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL], individual: result.types[AddonMessagesMessageConversationType.INDIVIDUAL],
group: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP], group: result.types[AddonMessagesMessageConversationType.GROUP],
self: result.types[AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_SELF] || 0, self: result.types[AddonMessagesMessageConversationType.SELF] || 0,
}; };
} else { } else {
@ -1592,7 +1663,7 @@ export class AddonMessagesProvider {
} }
// Notify the new counts so all views are updated. // Notify the new counts so all views are updated.
CoreEvents.trigger(AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT, counts, site.id); CoreEvents.trigger(ADDON_MESSAGES_UNREAD_CONVERSATION_COUNTS_EVENT, counts, site.id);
return counts; return counts;
} }
@ -1617,7 +1688,7 @@ export class AddonMessagesProvider {
const params: AddonMessagesGetMessagesWSParams = { const params: AddonMessagesGetMessagesWSParams = {
read: false, read: false,
limitfrom: 0, limitfrom: 0,
limitnum: AddonMessagesProvider.LIMIT_MESSAGES, limitnum: ADDON_MESSAGES_LIMIT_MESSAGES,
useridto: site.getUserId(), useridto: site.getUserId(),
useridfrom: 0, useridfrom: 0,
}; };
@ -1863,7 +1934,7 @@ export class AddonMessagesProvider {
* @returns Promise resolved when done. * @returns Promise resolved when done.
*/ */
protected async invalidateAllMemberInfo(userId: number, site: CoreSite): Promise<void> { protected async invalidateAllMemberInfo(userId: number, site: CoreSite): Promise<void> {
await CoreUtils.allPromises([ await CorePromiseUtils.allPromises([
this.invalidateMemberInfo(userId, site.id), this.invalidateMemberInfo(userId, site.id),
this.invalidateUserContacts(site.id), this.invalidateUserContacts(site.id),
this.invalidateBlockedContactsCache(site.id), this.invalidateBlockedContactsCache(site.id),
@ -1881,7 +1952,7 @@ export class AddonMessagesProvider {
site.id, site.id,
undefined, undefined,
true, true,
).then((conversation) => CoreUtils.allPromises([ ).then((conversation) => CorePromiseUtils.allPromises([
this.invalidateConversation(conversation.id), this.invalidateConversation(conversation.id),
this.invalidateConversationMembers(conversation.id, site.id), this.invalidateConversationMembers(conversation.id, site.id),
])).catch(() => { ])).catch(() => {
@ -2243,13 +2314,13 @@ export class AddonMessagesProvider {
await site.write('core_message_delete_contacts', params, preSets); await site.write('core_message_delete_contacts', params, preSets);
return CoreUtils.allPromises([ return CorePromiseUtils.allPromises([
this.invalidateUserContacts(site.id), this.invalidateUserContacts(site.id),
this.invalidateAllMemberInfo(userId, site), this.invalidateAllMemberInfo(userId, site),
this.invalidateContactsCache(site.id), this.invalidateContactsCache(site.id),
]).then(() => { ]).then(() => {
const data: AddonMessagesMemberInfoChangedEventData = { userId, contactRemoved: true }; const data: AddonMessagesMemberInfoChangedEventData = { userId, contactRemoved: true };
CoreEvents.trigger(AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, data, site.id); CoreEvents.trigger(ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT, data, site.id);
return; return;
}); });
@ -2296,7 +2367,7 @@ export class AddonMessagesProvider {
* @param query The query string. * @param query The query string.
* @param userId The user ID. If not defined, current user. * @param userId The user ID. If not defined, current user.
* @param limitFrom Position of the first result to get. Defaults to 0. * @param limitFrom Position of the first result to get. Defaults to 0.
* @param limitNum Number of results to get. Defaults to AddonMessagesProvider.LIMIT_SEARCH. * @param limitNum Number of results to get. Defaults to ADDON_MESSAGES_LIMIT_SEARCH.
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @returns Promise resolved with the results. * @returns Promise resolved with the results.
*/ */
@ -2304,7 +2375,7 @@ export class AddonMessagesProvider {
query: string, query: string,
userId?: number, userId?: number,
limitFrom: number = 0, limitFrom: number = 0,
limitNum: number = AddonMessagesProvider.LIMIT_SEARCH, limitNum: number = ADDON_MESSAGES_LIMIT_SEARCH,
siteId?: string, siteId?: string,
): Promise<{messages: AddonMessagesMessageAreaContact[]; canLoadMore: boolean}> { ): Promise<{messages: AddonMessagesMessageAreaContact[]; canLoadMore: boolean}> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
@ -2349,7 +2420,7 @@ export class AddonMessagesProvider {
* *
* @param query Text to search for. * @param query Text to search for.
* @param limitFrom Position of the first found user to fetch. * @param limitFrom Position of the first found user to fetch.
* @param limitNum Number of found users to fetch. Defaults to AddonMessagesProvider.LIMIT_SEARCH. * @param limitNum Number of found users to fetch. Defaults to ADDON_MESSAGES_LIMIT_SEARCH.
* @param siteId Site ID. If not defined, use current site. * @param siteId Site ID. If not defined, use current site.
* @returns Resolved with two lists of found users: contacts and non-contacts. * @returns Resolved with two lists of found users: contacts and non-contacts.
* @since 3.6 * @since 3.6
@ -2357,7 +2428,7 @@ export class AddonMessagesProvider {
async searchUsers( async searchUsers(
query: string, query: string,
limitFrom: number = 0, limitFrom: number = 0,
limitNum: number = AddonMessagesProvider.LIMIT_SEARCH, limitNum: number = ADDON_MESSAGES_LIMIT_SEARCH,
siteId?: string, siteId?: string,
): Promise<{ ): Promise<{
contacts: AddonMessagesConversationMember[]; contacts: AddonMessagesConversationMember[];
@ -2459,7 +2530,7 @@ export class AddonMessagesProvider {
message: result, message: result,
}; };
} catch (error) { } catch (error) {
if (CoreUtils.isWebServiceError(error)) { if (CoreWSError.isWebServiceError(error)) {
// It's a WebService error, the user cannot send the message so don't store it. // It's a WebService error, the user cannot send the message so don't store it.
throw error; throw error;
} }
@ -2590,7 +2661,7 @@ export class AddonMessagesProvider {
message: result, message: result,
}; };
} catch (error) { } catch (error) {
if (CoreUtils.isWebServiceError(error)) { if (CoreWSError.isWebServiceError(error)) {
// It's a WebService error, the user cannot send the message so don't store it. // It's a WebService error, the user cannot send the message so don't store it.
throw error; throw error;
} }
@ -2827,7 +2898,7 @@ export class AddonMessagesProvider {
} finally { } finally {
const data: AddonMessagesMemberInfoChangedEventData = { userId, userUnblocked: true }; const data: AddonMessagesMemberInfoChangedEventData = { userId, userUnblocked: true };
CoreEvents.trigger(AddonMessagesProvider.MEMBER_INFO_CHANGED_EVENT, data, site.id); CoreEvents.trigger(ADDON_MESSAGES_MEMBER_INFO_CHANGED_EVENT, data, site.id);
} }
} }

View File

@ -16,7 +16,7 @@ import { Params } from '@angular/router';
import { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source'; import { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source';
import { CoreGroupInfo, CoreGroups } from '@services/groups'; import { CoreGroupInfo, CoreGroups } from '@services/groups';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreIonicColorNames } from '@singletons/colors'; import { CoreIonicColorNames } from '@singletons/colors';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
@ -194,7 +194,7 @@ export class AddonModAssignSubmissionsSource extends CoreRoutedItemsManagerSourc
const showSubmissions: AddonModAssignSubmissionForList[] = await Promise.all( const showSubmissions: AddonModAssignSubmissionForList[] = await Promise.all(
submissions.map(async (submission: AddonModAssignSubmissionForList) => { submissions.map(async (submission: AddonModAssignSubmissionForList) => {
const gradeData = const gradeData =
await CoreUtils.ignoreErrors(AddonModAssignOffline.getSubmissionGrade(assign.id, submission.userid)); await CorePromiseUtils.ignoreErrors(AddonModAssignOffline.getSubmissionGrade(assign.id, submission.userid));
// Load offline grades. // Load offline grades.
const notSynced = !!gradeData && submission.timemodified < gradeData.timemodified; const notSynced = !!gradeData && submission.timemodified < gradeData.timemodified;

View File

@ -16,7 +16,7 @@ import { Component, Input, ViewChild, ElementRef } from '@angular/core';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreFormFields, CoreForms } from '@singletons/form'; import { CoreFormFields, CoreForms } from '@singletons/form';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { ModalController, Translate } from '@singletons'; import { ModalController, Translate } from '@singletons';
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../../services/assign'; import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../../services/assign';
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate'; import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
@ -88,7 +88,7 @@ export class AddonModAssignEditFeedbackModalComponent {
* @returns Promise resolved with boolean: whether the data has changed. * @returns Promise resolved with boolean: whether the data has changed.
*/ */
protected async hasDataChanged(): Promise<boolean> { protected async hasDataChanged(): Promise<boolean> {
const changed = await CoreUtils.ignoreErrors( const changed = await CorePromiseUtils.ignoreErrors(
AddonModAssignFeedbackDelegate.hasPluginDataChanged( AddonModAssignFeedbackDelegate.hasPluginDataChanged(
this.assign, this.assign,
this.submission, this.submission,

View File

@ -24,7 +24,7 @@ import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreTime } from '@singletons/time'; import { CoreTime } from '@singletons/time';
@ -182,7 +182,7 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
if (sync) { if (sync) {
// Try to synchronize the assign. // Try to synchronize the assign.
await CoreUtils.ignoreErrors(this.syncActivity(showErrors)); await CorePromiseUtils.ignoreErrors(this.syncActivity(showErrors));
} }
// Check if there's any offline data for this assign. // Check if there's any offline data for this assign.
@ -250,18 +250,18 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
return; // Shouldn't happen. return; // Shouldn't happen.
} }
await CoreUtils.ignoreErrors(AddonModAssign.logView(this.assign.id)); await CorePromiseUtils.ignoreErrors(AddonModAssign.logView(this.assign.id));
this.analyticsLogEvent('mod_assign_view_assign'); this.analyticsLogEvent('mod_assign_view_assign');
if (this.canViewAllSubmissions) { if (this.canViewAllSubmissions) {
// User can see all submissions, log grading view. // User can see all submissions, log grading view.
await CoreUtils.ignoreErrors(AddonModAssign.logGradingView(this.assign.id)); await CorePromiseUtils.ignoreErrors(AddonModAssign.logGradingView(this.assign.id));
this.analyticsLogEvent('mod_assign_view_grading_table', { sendUrl: false }); this.analyticsLogEvent('mod_assign_view_grading_table', { sendUrl: false });
} else if (this.canViewOwnSubmission) { } else if (this.canViewOwnSubmission) {
// User can only see their own submission, log view the user submission. // User can only see their own submission, log view the user submission.
await CoreUtils.ignoreErrors(AddonModAssign.logSubmissionView(this.assign.id)); await CorePromiseUtils.ignoreErrors(AddonModAssign.logSubmissionView(this.assign.id));
this.analyticsLogEvent('mod_assign_view_submission_status', { sendUrl: false }); this.analyticsLogEvent('mod_assign_view_submission_status', { sendUrl: false });
} }

View File

@ -37,7 +37,7 @@ import { CoreTabsComponent } from '@components/tabs/tabs';
import { CoreTabComponent } from '@components/tabs/tab'; import { CoreTabComponent } from '@components/tabs/tab';
import { CoreSplitViewComponent } from '@components/split-view/split-view'; import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { CoreGradesFormattedItem, CoreGradesHelper } from '@features/grades/services/grades-helper'; import { CoreGradesFormattedItem, CoreGradesHelper } from '@features/grades/services/grades-helper';
import { CoreMenuItem, CoreUtils } from '@services/utils/utils'; import { CoreMenuItem, CoreUtils } from '@singletons/utils';
import { AddonModAssignHelper, AddonModAssignSubmissionFormatted } from '../../services/assign-helper'; import { AddonModAssignHelper, AddonModAssignSubmissionFormatted } from '../../services/assign-helper';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { Translate } from '@singletons'; import { Translate } from '@singletons';
@ -70,6 +70,7 @@ import {
} from '../../constants'; } from '../../constants';
import { CoreViewer } from '@features/viewer/services/viewer'; import { CoreViewer } from '@features/viewer/services/viewer';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Component that displays an assignment submission. * Component that displays an assignment submission.
@ -77,7 +78,7 @@ import { CoreLoadings } from '@services/loadings';
@Component({ @Component({
selector: 'addon-mod-assign-submission', selector: 'addon-mod-assign-submission',
templateUrl: 'addon-mod-assign-submission.html', templateUrl: 'addon-mod-assign-submission.html',
styleUrls: ['submission.scss'], styleUrl: 'submission.scss',
}) })
export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, CanLeave { export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, CanLeave {
@ -327,7 +328,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
const previousSubmission = this.previousAttempt.submission; const previousSubmission = this.previousAttempt.submission;
let modal = await CoreLoadings.show(); let modal = await CoreLoadings.show();
const size = await CoreUtils.ignoreErrors( const size = await CorePromiseUtils.ignoreErrors(
AddonModAssignHelper.getSubmissionSizeForCopy(this.assign, previousSubmission), AddonModAssignHelper.getSubmissionSizeForCopy(this.assign, previousSubmission),
-1, -1,
); // Error calculating size, return -1. ); // Error calculating size, return -1.
@ -548,7 +549,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
}); });
} }
await CoreUtils.ignoreErrors(Promise.all(promises)); await CorePromiseUtils.ignoreErrors(Promise.all(promises));
await this.loadData(sync); await this.loadData(sync);
} }
@ -716,7 +717,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
// If we have data about the grader, get its profile. // If we have data about the grader, get its profile.
if (feedback.grade && feedback.grade.grader > 0) { if (feedback.grade && feedback.grade.grader > 0) {
this.grader = await CoreUtils.ignoreErrors(CoreUser.getProfile(feedback.grade.grader, this.courseId)); this.grader = await CorePromiseUtils.ignoreErrors(CoreUser.getProfile(feedback.grade.grader, this.courseId));
} else { } else {
delete this.grader; delete this.grader;
} }
@ -803,7 +804,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
// Submission grades aren't identified by attempt number so it can retrieve the feedback for a previous attempt. // Submission grades aren't identified by attempt number so it can retrieve the feedback for a previous attempt.
// The app will not treat that as an special case. // The app will not treat that as an special case.
const submissionGrade = await CoreUtils.ignoreErrors( const submissionGrade = await CorePromiseUtils.ignoreErrors(
AddonModAssignOffline.getSubmissionGrade(assign.id, this.submitId), AddonModAssignOffline.getSubmissionGrade(assign.id, this.submitId),
); );
@ -1075,7 +1076,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
const [gradebookGrades, assignGrades] = await Promise.all([ const [gradebookGrades, assignGrades] = await Promise.all([
CoreGradesHelper.getGradeModuleItems(this.courseId, this.moduleId, this.submitId), CoreGradesHelper.getGradeModuleItems(this.courseId, this.moduleId, this.submitId),
gradeNotReleased ? gradeNotReleased ?
CoreUtils.ignoreErrors(AddonModAssign.getAssignmentGrades(assign.id, { cmId: assign.cmid })) : CorePromiseUtils.ignoreErrors(AddonModAssign.getAssignmentGrades(assign.id, { cmId: assign.cmid })) :
undefined, undefined,
]); ]);

View File

@ -23,7 +23,7 @@ import {
} from '../services/handler'; } from '../services/handler';
import { AddonModAssignFeedbackDelegate } from '@addons/mod/assign/services/feedback-delegate'; import { AddonModAssignFeedbackDelegate } from '@addons/mod/assign/services/feedback-delegate';
import { AddonModAssignOffline } from '@addons/mod/assign/services/assign-offline'; import { AddonModAssignOffline } from '@addons/mod/assign/services/assign-offline';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { AddonModAssignFeedbackPluginBaseComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component'; import { AddonModAssignFeedbackPluginBaseComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
import { ContextLevel } from '@/core/constants'; import { ContextLevel } from '@/core/constants';
import { ADDON_MOD_ASSIGN_COMPONENT } from '@addons/mod/assign/constants'; import { ADDON_MOD_ASSIGN_COMPONENT } from '@addons/mod/assign/constants';
@ -124,7 +124,7 @@ export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedb
} }
// There is no draft saved. Check if we have anything offline. // There is no draft saved. Check if we have anything offline.
const offlineData = await CoreUtils.ignoreErrors( const offlineData = await CorePromiseUtils.ignoreErrors(
AddonModAssignOffline.getSubmissionGrade(this.assign.id, this.userId), AddonModAssignOffline.getSubmissionGrade(this.assign.id, this.userId),
undefined, undefined,
); );

View File

@ -25,10 +25,9 @@ import { AddonModAssignFeedbackHandler } from '@addons/mod/assign/services/feedb
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModAssignFeedbackCommentsComponent } from '../component/comments';
import { CoreFileHelper } from '@services/file-helper'; import { CoreFileHelper } from '@services/file-helper';
/** /**
@ -73,7 +72,9 @@ export class AddonModAssignFeedbackCommentsHandlerService implements AddonModAss
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<IAddonModAssignFeedbackPluginComponent> { async getComponent(): Promise<Type<IAddonModAssignFeedbackPluginComponent>> {
const { AddonModAssignFeedbackCommentsComponent } = await import('../component/comments');
return AddonModAssignFeedbackCommentsComponent; return AddonModAssignFeedbackCommentsComponent;
} }
@ -124,7 +125,7 @@ export class AddonModAssignFeedbackCommentsHandlerService implements AddonModAss
userId: number, userId: number,
): Promise<boolean> { ): Promise<boolean> {
// Get it from plugin or offline. // Get it from plugin or offline.
const offlineData = await CoreUtils.ignoreErrors( const offlineData = await CorePromiseUtils.ignoreErrors(
AddonModAssignOffline.getSubmissionGrade(assign.id, userId), AddonModAssignOffline.getSubmissionGrade(assign.id, userId),
undefined, undefined,
); );

View File

@ -22,7 +22,6 @@ import { AddonModAssignFeedbackHandler } from '@addons/mod/assign/services/feedb
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModAssignFeedbackEditPdfComponent } from '../component/editpdf';
import type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component'; import type { IAddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
/** /**
@ -37,7 +36,9 @@ export class AddonModAssignFeedbackEditPdfHandlerService implements AddonModAssi
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<IAddonModAssignFeedbackPluginComponent> { async getComponent(): Promise<Type<IAddonModAssignFeedbackPluginComponent>> {
const { AddonModAssignFeedbackEditPdfComponent } = await import('../component/editpdf');
return AddonModAssignFeedbackEditPdfComponent; return AddonModAssignFeedbackEditPdfComponent;
} }

View File

@ -23,7 +23,6 @@ import { AddonModAssignFeedbackHandler } from '@addons/mod/assign/services/feedb
import { Injectable, Type } from '@angular/core'; import { Injectable, Type } from '@angular/core';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModAssignFeedbackFileComponent } from '../component/file';
/** /**
* Handler for file feedback plugin. * Handler for file feedback plugin.
@ -37,7 +36,9 @@ export class AddonModAssignFeedbackFileHandlerService implements AddonModAssignF
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<IAddonModAssignFeedbackPluginComponent> { async getComponent(): Promise<Type<IAddonModAssignFeedbackPluginComponent>> {
const { AddonModAssignFeedbackFileComponent } = await import('../component/file');
return AddonModAssignFeedbackFileComponent; return AddonModAssignFeedbackFileComponent;
} }

View File

@ -36,7 +36,7 @@ import {
import { AddonModAssignHelper } from '../../services/assign-helper'; import { AddonModAssignHelper } from '../../services/assign-helper';
import { AddonModAssignOffline } from '../../services/assign-offline'; import { AddonModAssignOffline } from '../../services/assign-offline';
import { AddonModAssignSync } from '../../services/assign-sync'; import { AddonModAssignSync } from '../../services/assign-sync';
import { CoreUtils } from '@services/utils/utils'; import { CoreWSError } from '@classes/errors/wserror';
import { CoreWSExternalFile } from '@services/ws'; import { CoreWSExternalFile } from '@services/ws';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { import {
@ -47,6 +47,7 @@ import {
} from '../../constants'; } from '../../constants';
import { CoreToasts, ToastDuration } from '@services/toasts'; import { CoreToasts, ToastDuration } from '@services/toasts';
import { CoreLoadings } from '@services/loadings'; import { CoreLoadings } from '@services/loadings';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Page that allows adding or editing an assigment submission. * Page that allows adding or editing an assigment submission.
@ -54,7 +55,7 @@ import { CoreLoadings } from '@services/loadings';
@Component({ @Component({
selector: 'page-addon-mod-assign-edit', selector: 'page-addon-mod-assign-edit',
templateUrl: 'edit.html', templateUrl: 'edit.html',
styleUrls: ['edit.scss'], styleUrl: 'edit.scss',
}) })
export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave { export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave {
@ -232,7 +233,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave {
} }
// Check if there's any offline data for this submission. // Check if there's any offline data for this submission.
this.hasOffline = await CoreUtils.promiseWorks(AddonModAssignOffline.getSubmission(this.assign.id, this.userId)); this.hasOffline = await CorePromiseUtils.promiseWorks(AddonModAssignOffline.getSubmission(this.assign.id, this.userId));
CoreAnalytics.logEvent({ CoreAnalytics.logEvent({
type: CoreAnalyticsEventType.VIEW_ITEM, type: CoreAnalyticsEventType.VIEW_ITEM,
@ -343,7 +344,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy, CanLeave {
this.hasOffline, this.hasOffline,
); );
} catch (error) { } catch (error) {
if (this.allowOffline && !this.saveOffline && !CoreUtils.isWebServiceError(error)) { if (this.allowOffline && !this.saveOffline && !CoreWSError.isWebServiceError(error)) {
// Cannot submit in online, prepare for offline usage. // Cannot submit in online, prepare for offline usage.
this.saveOffline = true; this.saveOffline = true;

View File

@ -27,7 +27,7 @@ import {
AddonModAssignSubmissionStatusValues, AddonModAssignSubmissionStatusValues,
} from './assign'; } from './assign';
import { AddonModAssignOffline } from './assign-offline'; import { AddonModAssignOffline } from './assign-offline';
import { CoreUtils } from '@services/utils/utils'; import { CoreObject } from '@singletons/object';
import { CoreFile } from '@services/file'; import { CoreFile } from '@services/file';
import { CoreCourseCommonModWSOptions } from '@features/course/services/course'; import { CoreCourseCommonModWSOptions } from '@features/course/services/course';
import { CoreGroups } from '@services/groups'; import { CoreGroups } from '@services/groups';
@ -37,6 +37,7 @@ import { makeSingleton } from '@singletons';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { CoreFileEntry } from '@services/file-helper'; import { CoreFileEntry } from '@services/file-helper';
import { ADDON_MOD_ASSIGN_COMPONENT } from '../constants'; import { ADDON_MOD_ASSIGN_COMPONENT } from '../constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Service that provides some helper functions for assign. * Service that provides some helper functions for assign.
@ -81,7 +82,7 @@ export class AddonModAssignHelperProvider {
return true; return true;
} }
if (await CoreUtils.promiseWorks(AddonModAssignOffline.getSubmission(assign.id, submission.userid))) { if (await CorePromiseUtils.promiseWorks(AddonModAssignOffline.getSubmission(assign.id, submission.userid))) {
// Submission was saved or deleted offline, allow editing it or creating a new one. // Submission was saved or deleted offline, allow editing it or creating a new one.
return true; return true;
} }
@ -313,7 +314,7 @@ export class AddonModAssignHelperProvider {
await Promise.all(promises); await Promise.all(promises);
return CoreUtils.objectToArray(participantsIndexed); return CoreObject.toArray(participantsIndexed);
} }
/** /**
@ -530,7 +531,7 @@ export class AddonModAssignHelperProvider {
const promises = feedback.plugins.map((plugin) => const promises = feedback.plugins.map((plugin) =>
this.prepareFeedbackPluginData(assign.id, userId, feedback).then(async (inputData) => { this.prepareFeedbackPluginData(assign.id, userId, feedback).then(async (inputData) => {
const changed = await CoreUtils.ignoreErrors( const changed = await CorePromiseUtils.ignoreErrors(
AddonModAssignFeedbackDelegate.hasPluginDataChanged(assign, submission, plugin, inputData, userId), AddonModAssignFeedbackDelegate.hasPluginDataChanged(assign, submission, plugin, inputData, userId),
false, false,
); );
@ -541,7 +542,7 @@ export class AddonModAssignHelperProvider {
return; return;
})); }));
await CoreUtils.allPromises(promises); await CorePromiseUtils.allPromises(promises);
return hasChanged; return hasChanged;
} }
@ -579,7 +580,7 @@ export class AddonModAssignHelperProvider {
})) }))
: []; : [];
await CoreUtils.allPromises(promises); await CorePromiseUtils.allPromises(promises);
return hasChanged; return hasChanged;
} }

View File

@ -33,13 +33,14 @@ import {
} from './assign-offline'; } from './assign-offline';
import { CoreSync, CoreSyncResult } from '@services/sync'; import { CoreSync, CoreSyncResult } from '@services/sync';
import { CoreCourseLogHelper } from '@features/course/services/log-helper'; import { CoreCourseLogHelper } from '@features/course/services/log-helper';
import { CoreUtils } from '@services/utils/utils'; import { CoreWSError } from '@classes/errors/wserror';
import { CoreNetwork } from '@services/network'; import { CoreNetwork } from '@services/network';
import { CoreNetworkError } from '@classes/errors/network-error'; import { CoreNetworkError } from '@classes/errors/network-error';
import { CoreGradesFormattedItem, CoreGradesHelper } from '@features/grades/services/grades-helper'; import { CoreGradesFormattedItem, CoreGradesHelper } from '@features/grades/services/grades-helper';
import { AddonModAssignSubmissionDelegate } from './submission-delegate'; import { AddonModAssignSubmissionDelegate } from './submission-delegate';
import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; import { AddonModAssignFeedbackDelegate } from './feedback-delegate';
import { ADDON_MOD_ASSIGN_AUTO_SYNCED, ADDON_MOD_ASSIGN_COMPONENT } from '../constants'; import { ADDON_MOD_ASSIGN_AUTO_SYNCED, ADDON_MOD_ASSIGN_COMPONENT, ADDON_MOD_ASSIGN_MANUAL_SYNCED } from '../constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Service to sync assigns. * Service to sync assigns.
@ -189,7 +190,7 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
*/ */
protected async performSyncAssign(assignId: number, siteId: string): Promise<AddonModAssignSyncResult> { protected async performSyncAssign(assignId: number, siteId: string): Promise<AddonModAssignSyncResult> {
// Sync offline logs. // Sync offline logs.
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
CoreCourseLogHelper.syncActivity(ADDON_MOD_ASSIGN_COMPONENT, assignId, siteId), CoreCourseLogHelper.syncActivity(ADDON_MOD_ASSIGN_COMPONENT, assignId, siteId),
); );
@ -207,7 +208,7 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
if (!submissions.length && !grades.length) { if (!submissions.length && !grades.length) {
// Nothing to sync. // Nothing to sync.
await CoreUtils.ignoreErrors(this.setSyncTime(assignId, siteId)); await CorePromiseUtils.ignoreErrors(this.setSyncTime(assignId, siteId));
return result; return result;
} }
@ -246,15 +247,15 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
} }
})); }));
await CoreUtils.allPromises(promises); await CorePromiseUtils.allPromises(promises);
if (result.updated) { if (result.updated) {
// Data has been sent to server. Now invalidate the WS calls. // Data has been sent to server. Now invalidate the WS calls.
await CoreUtils.ignoreErrors(AddonModAssign.invalidateContent(assign.cmid, courseId, siteId)); await CorePromiseUtils.ignoreErrors(AddonModAssign.invalidateContent(assign.cmid, courseId, siteId));
} }
// Sync finished, set sync time. // Sync finished, set sync time.
await CoreUtils.ignoreErrors(this.setSyncTime(assignId, siteId)); await CorePromiseUtils.ignoreErrors(this.setSyncTime(assignId, siteId));
// All done, return the result. // All done, return the result.
return result; return result;
@ -272,7 +273,7 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
siteId: string, siteId: string,
): Promise<AddonModAssignSubmissionsGradingDBRecordFormatted[]> { ): Promise<AddonModAssignSubmissionsGradingDBRecordFormatted[]> {
// If no offline data found, return empty array. // If no offline data found, return empty array.
return CoreUtils.ignoreErrors(AddonModAssignOffline.getAssignSubmissionsGrade(assignId, siteId), []); return CorePromiseUtils.ignoreErrors(AddonModAssignOffline.getAssignSubmissionsGrade(assignId, siteId), []);
} }
/** /**
@ -287,7 +288,7 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
siteId: string, siteId: string,
): Promise<AddonModAssignSubmissionsDBRecordFormatted[]> { ): Promise<AddonModAssignSubmissionsDBRecordFormatted[]> {
// If no offline data found, return empty array. // If no offline data found, return empty array.
return CoreUtils.ignoreErrors(AddonModAssignOffline.getAssignSubmissions(assignId, siteId), []); return CorePromiseUtils.ignoreErrors(AddonModAssignOffline.getAssignSubmissions(assignId, siteId), []);
} }
/** /**
@ -359,7 +360,7 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
// Submission data sent, update cached data. No need to block the user for this. // Submission data sent, update cached data. No need to block the user for this.
AddonModAssign.getSubmissionStatus(assign.id, options); AddonModAssign.getSubmissionStatus(assign.id, options);
} catch (error) { } catch (error) {
if (!error || !CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
// Local error, reject. // Local error, reject.
throw error; throw error;
} }
@ -508,9 +509,9 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
// Update cached data. // Update cached data.
promises.push(AddonModAssign.getSubmissionStatus(assign.id, options)); promises.push(AddonModAssign.getSubmissionStatus(assign.id, options));
await CoreUtils.allPromises(promises); await CorePromiseUtils.allPromises(promises);
} catch (error) { } catch (error) {
if (!error || !CoreUtils.isWebServiceError(error)) { if (!CoreWSError.isWebServiceError(error)) {
// Local error, reject. // Local error, reject.
throw error; throw error;
} }
@ -535,7 +536,7 @@ export type AddonModAssignSyncResult = CoreSyncResult & {
}; };
/** /**
* Data passed to AUTO_SYNCED event. * Data passed to ADDON_MOD_ASSIGN_AUTO_SYNCED event.
*/ */
export type AddonModAssignAutoSyncData = { export type AddonModAssignAutoSyncData = {
assignId: number; assignId: number;
@ -544,9 +545,23 @@ export type AddonModAssignAutoSyncData = {
}; };
/** /**
* Data passed to MANUAL_SYNCED event. * Data passed to ADDON_MOD_ASSIGN_MANUAL_SYNCED event.
*/ */
export type AddonModAssignManualSyncData = AddonModAssignAutoSyncData & { export type AddonModAssignManualSyncData = AddonModAssignAutoSyncData & {
context: string; context: string;
submitId?: number; submitId?: number;
}; };
declare module '@singletons/events' {
/**
* Augment CoreEventsData interface with events specific to this service.
*
* @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
*/
export interface CoreEventsData {
[ADDON_MOD_ASSIGN_MANUAL_SYNCED]: AddonModAssignManualSyncData;
[ADDON_MOD_ASSIGN_AUTO_SYNCED]: AddonModAssignAutoSyncData;
}
}

View File

@ -24,23 +24,19 @@ import { CoreTimeUtils } from '@services/utils/time';
import { CoreCourseLogHelper } from '@features/course/services/log-helper'; import { CoreCourseLogHelper } from '@features/course/services/log-helper';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { CoreNetwork } from '@services/network'; import { CoreNetwork } from '@services/network';
import { CoreUtils } from '@services/utils/utils';
import { AddonModAssignOffline } from './assign-offline'; import { AddonModAssignOffline } from './assign-offline';
import { AddonModAssignSubmissionDelegate } from './submission-delegate'; import { AddonModAssignSubmissionDelegate } from './submission-delegate';
import { CoreComments } from '@features/comments/services/comments'; import { CoreComments } from '@features/comments/services/comments';
import { AddonModAssignSubmissionFormatted } from './assign-helper'; import { AddonModAssignSubmissionFormatted } from './assign-helper';
import { CoreWSError } from '@classes/errors/wserror'; import { CoreWSError } from '@classes/errors/wserror';
import { AddonModAssignAutoSyncData, AddonModAssignManualSyncData } from './assign-sync';
import { CoreFormFields } from '@singletons/form'; import { CoreFormFields } from '@singletons/form';
import { CoreFileHelper } from '@services/file-helper'; import { CoreFileHelper } from '@services/file-helper';
import { CoreIonicColorNames } from '@singletons/colors'; import { CoreIonicColorNames } from '@singletons/colors';
import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site';
import { ContextLevel } from '@/core/constants'; import { ContextLevel, CoreCacheUpdateFrequency } from '@/core/constants';
import { import {
ADDON_MOD_ASSIGN_AUTO_SYNCED,
ADDON_MOD_ASSIGN_COMPONENT, ADDON_MOD_ASSIGN_COMPONENT,
ADDON_MOD_ASSIGN_GRADED_EVENT, ADDON_MOD_ASSIGN_GRADED_EVENT,
ADDON_MOD_ASSIGN_MANUAL_SYNCED,
ADDON_MOD_ASSIGN_STARTED_EVENT, ADDON_MOD_ASSIGN_STARTED_EVENT,
ADDON_MOD_ASSIGN_SUBMISSION_REMOVED_EVENT, ADDON_MOD_ASSIGN_SUBMISSION_REMOVED_EVENT,
ADDON_MOD_ASSIGN_SUBMISSION_SAVED_EVENT, ADDON_MOD_ASSIGN_SUBMISSION_SAVED_EVENT,
@ -60,8 +56,6 @@ declare module '@singletons/events' {
[ADDON_MOD_ASSIGN_SUBMITTED_FOR_GRADING_EVENT]: AddonModAssignSubmittedForGradingEventData; [ADDON_MOD_ASSIGN_SUBMITTED_FOR_GRADING_EVENT]: AddonModAssignSubmittedForGradingEventData;
[ADDON_MOD_ASSIGN_GRADED_EVENT]: AddonModAssignGradedEventData; [ADDON_MOD_ASSIGN_GRADED_EVENT]: AddonModAssignGradedEventData;
[ADDON_MOD_ASSIGN_STARTED_EVENT]: AddonModAssignStartedEventData; [ADDON_MOD_ASSIGN_STARTED_EVENT]: AddonModAssignStartedEventData;
[ADDON_MOD_ASSIGN_MANUAL_SYNCED]: AddonModAssignManualSyncData;
[ADDON_MOD_ASSIGN_AUTO_SYNCED]: AddonModAssignAutoSyncData;
} }
} }
@ -174,7 +168,7 @@ export class AddonModAssignProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getAssignmentCacheKey(courseId), cacheKey: this.getAssignmentCacheKey(courseId),
updateFrequency: CoreSite.FREQUENCY_RARELY, updateFrequency: CoreCacheUpdateFrequency.RARELY,
component: ADDON_MOD_ASSIGN_COMPONENT, component: ADDON_MOD_ASSIGN_COMPONENT,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets. ...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
}; };
@ -246,7 +240,7 @@ export class AddonModAssignProvider {
}; };
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getAssignmentUserMappingsCacheKey(assignId), cacheKey: this.getAssignmentUserMappingsCacheKey(assignId),
updateFrequency: CoreSite.FREQUENCY_OFTEN, updateFrequency: CoreCacheUpdateFrequency.OFTEN,
component: ADDON_MOD_ASSIGN_COMPONENT, component: ADDON_MOD_ASSIGN_COMPONENT,
componentId: options.cmId, componentId: options.cmId,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), ...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
@ -456,7 +450,7 @@ export class AddonModAssignProvider {
}; };
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.getSubmissionsCacheKey(assignId), cacheKey: this.getSubmissionsCacheKey(assignId),
updateFrequency: CoreSite.FREQUENCY_OFTEN, updateFrequency: CoreCacheUpdateFrequency.OFTEN,
component: ADDON_MOD_ASSIGN_COMPONENT, component: ADDON_MOD_ASSIGN_COMPONENT,
componentId: options.cmId, componentId: options.cmId,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), ...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
@ -654,7 +648,7 @@ export class AddonModAssignProvider {
const preSets: CoreSiteWSPreSets = { const preSets: CoreSiteWSPreSets = {
cacheKey: this.listParticipantsCacheKey(assignId, groupId), cacheKey: this.listParticipantsCacheKey(assignId, groupId),
updateFrequency: CoreSite.FREQUENCY_OFTEN, updateFrequency: CoreCacheUpdateFrequency.OFTEN,
component: ADDON_MOD_ASSIGN_COMPONENT, component: ADDON_MOD_ASSIGN_COMPONENT,
componentId: options.cmId, componentId: options.cmId,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), ...CoreSites.getReadingStrategyPreSets(options.readingStrategy),
@ -1025,7 +1019,7 @@ export class AddonModAssignProvider {
return true; return true;
} catch (error) { } catch (error) {
if (allowOffline && error && !CoreUtils.isWebServiceError(error)) { if (allowOffline && error && !CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return storeOffline(); return storeOffline();
} else { } else {
@ -1135,7 +1129,7 @@ export class AddonModAssignProvider {
return true; return true;
} catch (error) { } catch (error) {
if (error && !CoreUtils.isWebServiceError(error)) { if (error && !CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return storeOffline(); return storeOffline();
} else { } else {
@ -1243,7 +1237,7 @@ export class AddonModAssignProvider {
return true; return true;
} catch (error) { } catch (error) {
if (error && !CoreUtils.isWebServiceError(error)) { if (error && !CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return storeOffline(); return storeOffline();
} else { } else {
@ -1384,7 +1378,7 @@ export class AddonModAssignProvider {
return true; return true;
} catch (error) { } catch (error) {
if (error && !CoreUtils.isWebServiceError(error)) { if (error && !CoreWSError.isWebServiceError(error)) {
// Couldn't connect to server, store in offline. // Couldn't connect to server, store in offline.
return storeOffline(); return storeOffline();
} else { } else {

View File

@ -27,7 +27,7 @@ import { CoreCourseActivityPrefetchHandlerBase } from '@features/course/classes/
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseCommonModWSOptions } from '@features/course/services/course'; import { CoreCourse, CoreCourseAnyModuleData, CoreCourseCommonModWSOptions } from '@features/course/services/course';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { AddonModAssignHelper, AddonModAssignSubmissionFormatted } from '../assign-helper'; import { AddonModAssignHelper, AddonModAssignSubmissionFormatted } from '../assign-helper';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { CoreFilepool } from '@services/filepool'; import { CoreFilepool } from '@services/filepool';
import { CoreGroups } from '@services/groups'; import { CoreGroups } from '@services/groups';
import { AddonModAssignSync, AddonModAssignSyncResult } from '../assign-sync'; import { AddonModAssignSync, AddonModAssignSyncResult } from '../assign-sync';
@ -252,7 +252,7 @@ export class AddonModAssignPrefetchHandlerService extends CoreCourseActivityPref
if (blindMarking) { if (blindMarking) {
promises.push( promises.push(
CoreUtils.ignoreErrors(AddonModAssign.getAssignmentUserMappings(assign.id, -1, modOptions)), CorePromiseUtils.ignoreErrors(AddonModAssign.getAssignmentUserMappings(assign.id, -1, modOptions)),
); );
} }
@ -260,7 +260,7 @@ export class AddonModAssignPrefetchHandlerService extends CoreCourseActivityPref
promises.push(CoreCourse.getModuleBasicInfoByInstance(assign.id, 'assign', { siteId })); promises.push(CoreCourse.getModuleBasicInfoByInstance(assign.id, 'assign', { siteId }));
// Get course data, needed to determine upload max size if it's configured to be course limit. // Get course data, needed to determine upload max size if it's configured to be course limit.
promises.push(CoreUtils.ignoreErrors(CoreCourses.getCourseByField('id', courseId, siteId))); promises.push(CorePromiseUtils.ignoreErrors(CoreCourses.getCourseByField('id', courseId, siteId)));
// Download intro files and attachments. Do not call getFiles because it'd call some WS twice. // Download intro files and attachments. Do not call getFiles because it'd call some WS twice.
let files: CoreWSFile[] = assign.introattachments || []; let files: CoreWSFile[] = assign.introattachments || [];

View File

@ -17,10 +17,11 @@ import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate';
import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@singletons/utils';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModAssign } from '../assign'; import { AddonModAssign } from '../assign';
import { ADDON_MOD_ASSIGN_FEATURE_NAME } from '../../constants'; import { ADDON_MOD_ASSIGN_FEATURE_NAME } from '../../constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Handler for assign push notifications clicks. * Handler for assign push notifications clicks.
@ -54,7 +55,7 @@ export class AddonModAssignPushClickHandlerService implements CorePushNotificati
const courseId = Number(notification.courseid); const courseId = Number(notification.courseid);
const moduleId = Number(contextUrlParams.id); const moduleId = Number(contextUrlParams.id);
await CoreUtils.ignoreErrors(AddonModAssign.invalidateContent(moduleId, courseId, notification.site)); await CorePromiseUtils.ignoreErrors(AddonModAssign.invalidateContent(moduleId, courseId, notification.site));
await CoreCourseHelper.navigateToModule(moduleId, { await CoreCourseHelper.navigateToModule(moduleId, {
courseId, courseId,
siteId: notification.site, siteId: notification.site,

View File

@ -18,7 +18,7 @@ import { AddonModAssignOffline } from '@addons/mod/assign/services/assign-offlin
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader'; import { CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader';
import { CoreFileSession } from '@services/file-session'; import { CoreFileSession } from '@services/file-session';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { AddonModAssignSubmissionFileHandlerService } from '../services/handler'; import { AddonModAssignSubmissionFileHandlerService } from '../services/handler';
import { FileEntry } from '@awesome-cordova-plugins/file/ngx'; import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
import { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component'; import { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
@ -54,7 +54,7 @@ export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmiss
: undefined; : undefined;
// Get the offline data. // Get the offline data.
const offlineData = await CoreUtils.ignoreErrors( const offlineData = await CorePromiseUtils.ignoreErrors(
AddonModAssignOffline.getSubmission(this.assign.id), AddonModAssignOffline.getSubmission(this.assign.id),
undefined, undefined,
); );
@ -67,7 +67,7 @@ export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmiss
// It has offline data. // It has offline data.
let offlineFiles: FileEntry[] = []; let offlineFiles: FileEntry[] = [];
if (offlineDataFiles.offline) { if (offlineDataFiles.offline) {
offlineFiles = <FileEntry[]>await CoreUtils.ignoreErrors( offlineFiles = <FileEntry[]>await CorePromiseUtils.ignoreErrors(
AddonModAssignHelper.getStoredSubmissionFiles( AddonModAssignHelper.getStoredSubmissionFiles(
this.assign.id, this.assign.id,
AddonModAssignSubmissionFileHandlerService.FOLDER_NAME, AddonModAssignSubmissionFileHandlerService.FOLDER_NAME,

View File

@ -25,13 +25,13 @@ import { Injectable, Type } from '@angular/core';
import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader'; import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader';
import { CoreFileEntry, CoreFileHelper } from '@services/file-helper'; import { CoreFileEntry, CoreFileHelper } from '@services/file-helper';
import { CoreFileSession } from '@services/file-session'; import { CoreFileSession } from '@services/file-session';
import { CoreUtils } from '@services/utils/utils'; import { CoreFileUtils } from '@singletons/file-utils';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonModAssignSubmissionFileComponent } from '../component/file';
import { FileEntry } from '@awesome-cordova-plugins/file/ngx'; import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component'; import type { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
import { ADDON_MOD_ASSIGN_COMPONENT } from '@addons/mod/assign/constants'; import { ADDON_MOD_ASSIGN_COMPONENT } from '@addons/mod/assign/constants';
import { CorePromiseUtils } from '@singletons/promise-utils';
/** /**
* Handler for file submission plugin. * Handler for file submission plugin.
@ -101,7 +101,9 @@ export class AddonModAssignSubmissionFileHandlerService implements AddonModAssig
/** /**
* @inheritdoc * @inheritdoc
*/ */
getComponent(): Type<AddonModAssignSubmissionPluginBaseComponent> { async getComponent(): Promise<Type<AddonModAssignSubmissionPluginBaseComponent>> {
const { AddonModAssignSubmissionFileComponent } = await import('../component/file');
return AddonModAssignSubmissionFileComponent; return AddonModAssignSubmissionFileComponent;
} }
@ -116,7 +118,7 @@ export class AddonModAssignSubmissionFileHandlerService implements AddonModAssig
siteId?: string, siteId?: string,
): Promise<void> { ): Promise<void> {
await CoreUtils.ignoreErrors( await CorePromiseUtils.ignoreErrors(
AddonModAssignHelper.deleteStoredSubmissionFiles( AddonModAssignHelper.deleteStoredSubmissionFiles(
assign.id, assign.id,
AddonModAssignSubmissionFileHandlerService.FOLDER_NAME, AddonModAssignSubmissionFileHandlerService.FOLDER_NAME,
@ -174,7 +176,7 @@ export class AddonModAssignSubmissionFileHandlerService implements AddonModAssig
submission: AddonModAssignSubmission, submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin, plugin: AddonModAssignPlugin,
): Promise<boolean> { ): Promise<boolean> {
const offlineData = await CoreUtils.ignoreErrors( const offlineData = await CorePromiseUtils.ignoreErrors(
// Check if there's any offline data. // Check if there's any offline data.
AddonModAssignOffline.getSubmission(assign.id, submission.userid), AddonModAssignOffline.getSubmission(assign.id, submission.userid),
undefined, undefined,
@ -240,7 +242,7 @@ export class AddonModAssignSubmissionFileHandlerService implements AddonModAssig
// Data has changed, we need to upload new files and re-upload all the existing files. // Data has changed, we need to upload new files and re-upload all the existing files.
const currentFiles = CoreFileSession.getFiles(ADDON_MOD_ASSIGN_COMPONENT, assign.id); const currentFiles = CoreFileSession.getFiles(ADDON_MOD_ASSIGN_COMPONENT, assign.id);
const error = CoreUtils.hasRepeatedFilenames(currentFiles); const error = CoreFileUtils.hasRepeatedFilenames(currentFiles);
if (error) { if (error) {
throw error; throw error;
@ -302,7 +304,7 @@ export class AddonModAssignSubmissionFileHandlerService implements AddonModAssig
if (filesData.offline) { if (filesData.offline) {
// Has offline files, get them and add them to the list. // Has offline files, get them and add them to the list.
const storedFiles = <FileEntry[]> await CoreUtils.ignoreErrors( const storedFiles = <FileEntry[]> await CorePromiseUtils.ignoreErrors(
AddonModAssignHelper.getStoredSubmissionFiles( AddonModAssignHelper.getStoredSubmissionFiles(
assign.id, assign.id,
AddonModAssignSubmissionFileHandlerService.FOLDER_NAME, AddonModAssignSubmissionFileHandlerService.FOLDER_NAME,

View File

@ -19,7 +19,7 @@ import { Component, OnInit, ElementRef } from '@angular/core';
import { FormBuilder, FormControl } from '@angular/forms'; import { FormBuilder, FormControl } from '@angular/forms';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CoreUtils } from '@services/utils/utils'; import { CorePromiseUtils } from '@singletons/promise-utils';
import { AddonModAssignSubmissionOnlineTextPluginData } from '../services/handler'; import { AddonModAssignSubmissionOnlineTextPluginData } from '../services/handler';
import { ContextLevel } from '@/core/constants'; import { ContextLevel } from '@/core/constants';
import { ADDON_MOD_ASSIGN_COMPONENT } from '@addons/mod/assign/constants'; import { ADDON_MOD_ASSIGN_COMPONENT } from '@addons/mod/assign/constants';
@ -60,7 +60,7 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS
*/ */
async ngOnInit(): Promise<void> { async ngOnInit(): Promise<void> {
// Get the text. Check if we have anything offline. // Get the text. Check if we have anything offline.
const offlineData = await CoreUtils.ignoreErrors( const offlineData = await CorePromiseUtils.ignoreErrors(
AddonModAssignOffline.getSubmission(this.assign.id), AddonModAssignOffline.getSubmission(this.assign.id),
undefined, undefined,
); );

Some files were not shown because too many files have changed in this diff Show More