Noel De Martin 3621bc46a5 MOBILE-3947 glossary: Fix tests
There were some bugs in Angular v10 that countered this bug in our code, that's why it wasn't manifested until now. It seems to be related with the changes in createUrlTreeFromSegmentGroup.

See https://github.com/angular/angular/commits/16.0.x/packages/router/src/create_url_tree.ts?since=2020-06-25&until=2024-01-11
2024-01-15 16:35:57 +01:00

223 lines
7.7 KiB
TypeScript

// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { AddonLegacyNotificationsNotificationsSource } from '@addons/notifications/classes/legacy-notifications-source';
import { AddonNotificationsNotificationsSource } from '@addons/notifications/classes/notifications-source';
import { AddonNotificationsPushNotification } from '@addons/notifications/services/handlers/push-click';
import { AddonNotifications, AddonNotificationsNotificationMessageFormatted } from '@addons/notifications/services/notifications';
import {
AddonNotificationsHelper,
} from '@addons/notifications/services/notifications-helper';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router';
import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker';
import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager';
import { CoreContentLinksAction, CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics';
import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { Translate } from '@singletons';
/**
* Page to render a notification.
*/
@Component({
selector: 'page-addon-notifications-notification',
templateUrl: 'notification.html',
styleUrls: ['../../notifications.scss', 'notification.scss'],
})
export class AddonNotificationsNotificationPage implements OnInit, OnDestroy {
notifications?: AddonNotificationSwipeItemsManager;
notification?: AddonNotificationsNotificationMessageFormatted;
profileImageUrlFrom?: string; // Avatar of the user who sent the notification.
loaded = false;
// Actions data.
actions: CoreContentLinksAction[] = [];
protected contextUrl?: string;
protected courseId?: number;
protected actionsData?: Record<string, string|number>; // Extra data to handle the URL.
/**
* @inheritdoc
*/
async ngOnInit(): Promise<void> {
let notification: AddonNotificationsNotification;
try {
notification = this.getNotification();
} catch (error) {
CoreDomUtils.showErrorModal(error);
CoreNavigator.back();
return;
}
this.notification = 'subject' in notification ?
notification :
await AddonNotifications.convertPushToMessage(notification);
await this.loadActions(this.notification);
AddonNotificationsHelper.markNotificationAsRead(notification);
this.loaded = true;
if (notification.id) {
CoreAnalytics.logEvent({
type: CoreAnalyticsEventType.VIEW_ITEM,
ws: 'core_message_get_messages',
name: Translate.instant('addon.notifications.notifications'),
data: { id: notification.id, category: 'notifications' },
url: `/message/output/popup/notifications.php?notificationid=${notification.id}&offset=0`,
});
}
}
/**
* Get notification.
*
* @returns notification.
*/
getNotification(): AddonNotificationsNotification {
const id = CoreNavigator.getRouteNumberParam('id');
const notification = id ? this.getNotificationById(id) : undefined;
return notification ?? CoreNavigator.getRequiredRouteParam('notification');
}
/**
* Obtain notification by passed id.
*
* @param notificationId Notification id.
* @returns Found notification.
*/
getNotificationById(notificationId: number): AddonNotificationsNotification | undefined {
const source = CoreRoutedItemsManagerSourcesTracker.getOrCreateSource(
CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('4.0')
? AddonNotificationsNotificationsSource
: AddonLegacyNotificationsNotificationsSource,
[],
);
const notification = source.getItems()?.find(({ id }) => id === notificationId);
if (!notification) {
return;
}
this.loadNotifications(source);
return notification;
}
/**
* Load notifications from source.
*
* @param source Notifications source
*/
async loadNotifications(source: AddonNotificationsNotificationsSource): Promise<void> {
this.notifications = new AddonNotificationSwipeItemsManager(source);
await this.notifications.start();
}
/**
* Load notification actions
*
* @param notification Notification.
* @returns Promise resolved when done.
*/
async loadActions(notification: AddonNotificationsNotificationMessageFormatted): Promise<void> {
if (!notification.contexturl && (!notification.customdata || !notification.customdata.appurl)) {
// No URL, nothing to do.
return;
}
let actions: CoreContentLinksAction[] = [];
this.actionsData = notification.customdata;
this.contextUrl = notification.contexturl || undefined;
this.courseId = 'courseid' in notification ? notification.courseid : undefined;
// Treat appurl first if any.
if (this.actionsData?.appurl) {
actions = await CoreContentLinksDelegate.getActionsFor(
<string> this.actionsData.appurl,
this.courseId,
undefined,
this.actionsData,
);
}
if (!actions.length && this.contextUrl) {
// No appurl or cannot handle it. Try with contextUrl.
actions = await CoreContentLinksDelegate.getActionsFor(this.contextUrl, this.courseId, undefined, this.actionsData);
}
if (!actions.length) {
// URL is not supported. Add an action to open it in browser.
actions.push({
message: 'core.view',
icon: 'fas-eye',
action: (siteId) => this.openInBrowser(siteId),
});
}
this.actions = actions;
}
/**
* Default action. Open in browser.
*
* @param siteId Site ID to use.
*/
protected async openInBrowser(siteId?: string): Promise<void> {
const url = <string> this.actionsData?.appurl || this.contextUrl;
if (!url) {
return;
}
const site = await CoreSites.getSite(siteId);
site.openInBrowserWithAutoLogin(url);
}
/**
* @inheritdoc
*/
ngOnDestroy(): void {
this.notifications?.destroy();
}
}
/**
* Helper to manage swiping within a collection of notifications.
*/
class AddonNotificationSwipeItemsManager extends CoreSwipeNavigationItemsManager {
/**
* @inheritdoc
*/
protected getSelectedItemPathFromRoute(route: ActivatedRouteSnapshot | ActivatedRoute): string | null {
const snapshot = route instanceof ActivatedRouteSnapshot ? route : route.snapshot;
return snapshot.params.id;
}
}
type AddonNotificationsNotification = AddonNotificationsNotificationMessageFormatted | AddonNotificationsPushNotification;