From 90aededf123ccfdfcf1822b65620bcd0612dd8e9 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Mon, 8 May 2023 10:34:58 +0200 Subject: [PATCH] MOBILE-4270 notifications: Always display icon in notification --- scripts/langindex.json | 1 + .../classes/legacy-notifications-source.ts | 10 +-- .../classes/notifications-source.ts | 13 ++-- src/addons/notifications/notifications.scss | 10 +++ src/addons/notifications/pages/list/list.html | 17 ++--- src/addons/notifications/pages/list/list.ts | 5 +- .../pages/notification/notification.html | 34 ++++----- .../pages/notification/notification.ts | 52 ++++---------- .../services/handlers/push-click.ts | 8 +-- .../services/notifications-helper.ts | 29 ++------ .../notifications/services/notifications.ts | 71 +++++++++++++++---- .../services/pushnotifications.ts | 4 +- src/core/features/user/services/user.ts | 5 ++ src/core/lang.json | 1 + 14 files changed, 139 insertions(+), 121 deletions(-) diff --git a/scripts/langindex.json b/scripts/langindex.json index 051f03dde..53430cdc7 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -2202,6 +2202,7 @@ "core.nopermissionerror": "local_moodlemobileapp", "core.nopermissions": "error", "core.nopermissiontoaccesspage": "error", + "core.noreplyname": "moodle", "core.noresults": "moodle", "core.noselection": "form", "core.notapplicable": "local_moodlemobileapp", diff --git a/src/addons/notifications/classes/legacy-notifications-source.ts b/src/addons/notifications/classes/legacy-notifications-source.ts index 564689350..22319ca5f 100644 --- a/src/addons/notifications/classes/legacy-notifications-source.ts +++ b/src/addons/notifications/classes/legacy-notifications-source.ts @@ -13,8 +13,10 @@ // limitations under the License. import { AddonNotificationsNotificationsSource } from '@addons/notifications/classes/notifications-source'; -import { AddonNotificationsGetReadType } from '@addons/notifications/services/notifications'; -import { AddonNotificationsNotificationToRender } from '@addons/notifications/services/notifications-helper'; +import { + AddonNotificationsGetReadType, + AddonNotificationsNotificationMessageFormatted, +} from '@addons/notifications/services/notifications'; /** * Provides a list of notifications using legacy web services. @@ -25,10 +27,10 @@ export class AddonLegacyNotificationsNotificationsSource extends AddonNotificati * @inheritdoc */ protected async loadPageItems(page: number): Promise<{ - items: AddonNotificationsNotificationToRender[]; + items: AddonNotificationsNotificationMessageFormatted[]; hasMoreItems: boolean; }> { - let items: AddonNotificationsNotificationToRender[] = []; + let items: AddonNotificationsNotificationMessageFormatted[] = []; let hasMoreItems = false; let pageUnreadCount = 0; const pageLength = this.getPageLength(); diff --git a/src/addons/notifications/classes/notifications-source.ts b/src/addons/notifications/classes/notifications-source.ts index 4ff8edb85..033201956 100644 --- a/src/addons/notifications/classes/notifications-source.ts +++ b/src/addons/notifications/classes/notifications-source.ts @@ -15,22 +15,23 @@ import { AddonNotifications, AddonNotificationsGetReadType, + AddonNotificationsNotificationMessageFormatted, AddonNotificationsProvider, } from '@addons/notifications/services/notifications'; -import { AddonNotificationsNotificationToRender } from '@addons/notifications/services/notifications-helper'; import { CoreRoutedItemsManagerSource } from '@classes/items-management/routed-items-manager-source'; /** * Provides a list of notifications. */ -export class AddonNotificationsNotificationsSource extends CoreRoutedItemsManagerSource { +export class AddonNotificationsNotificationsSource + extends CoreRoutedItemsManagerSource { protected totals: Record = {}; /** * @inheritdoc */ - getItemPath(notification: AddonNotificationsNotificationToRender): string { + getItemPath(notification: AddonNotificationsNotificationMessageFormatted): string { return notification.id.toString(); } @@ -47,7 +48,7 @@ export class AddonNotificationsNotificationsSource extends CoreRoutedItemsManage * @inheritdoc */ protected async loadPageItems(page: number): Promise<{ - items: AddonNotificationsNotificationToRender[]; + items: AddonNotificationsNotificationMessageFormatted[]; hasMoreItems: boolean; }> { const results = await this.loadNotifications(AddonNotificationsGetReadType.BOTH, page * this.getPageLength()); @@ -67,7 +68,7 @@ export class AddonNotificationsNotificationsSource extends CoreRoutedItemsManage * @returns Notifications and whether there are any more. */ protected async loadNotifications(type: AddonNotificationsGetReadType, offset: number, limit?: number): Promise<{ - notifications: AddonNotificationsNotificationToRender[]; + notifications: AddonNotificationsNotificationMessageFormatted[]; hasMoreNotifications: boolean; }> { limit = limit ?? this.getPageLength(); @@ -94,7 +95,7 @@ export class AddonNotificationsNotificationsSource extends CoreRoutedItemsManage /** * @inheritdoc */ - protected setItems(notifications: AddonNotificationsNotificationToRender[], hasMoreItems: boolean): void { + protected setItems(notifications: AddonNotificationsNotificationMessageFormatted[], hasMoreItems: boolean): void { const sortedNotifications = notifications.slice(0); sortedNotifications.sort((a, b) => a.timecreated < b.timecreated ? 1 : -1); diff --git a/src/addons/notifications/notifications.scss b/src/addons/notifications/notifications.scss index 0583e27fa..2f144dd2a 100644 --- a/src/addons/notifications/notifications.scss +++ b/src/addons/notifications/notifications.scss @@ -34,6 +34,9 @@ width: var(--icon-size); height: var(--icon-size); } + ion-icon { + font-size: var(--icon-size); + } padding: 0.7rem; background: var(--background-color); border-radius: var(--small-radius); @@ -43,4 +46,11 @@ --module-icon-size: var(--icon-size); @include margin(6px, 8px, 6px, 0px); } + + .core-notification-img { + @include margin(6px, 8px, 6px, 0px); + width: var(--core-avatar-size); + height: var(--core-avatar-size); + object-fit: cover; + } } diff --git a/src/addons/notifications/pages/list/list.html b/src/addons/notifications/pages/list/list.html index c0ccfd14d..b7f7a5897 100644 --- a/src/addons/notifications/pages/list/list.html +++ b/src/addons/notifications/pages/list/list.html @@ -28,21 +28,18 @@ -
+
- - - -
- + + +
+ +
- -
diff --git a/src/addons/notifications/pages/list/list.ts b/src/addons/notifications/pages/list/list.ts index e26e0f344..dc935a079 100644 --- a/src/addons/notifications/pages/list/list.ts +++ b/src/addons/notifications/pages/list/list.ts @@ -20,7 +20,7 @@ import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { - AddonNotifications, AddonNotificationsProvider, + AddonNotifications, AddonNotificationsNotificationMessageFormatted, AddonNotificationsProvider, } from '../../services/notifications'; import { CoreNavigator } from '@services/navigator'; import { CoreSplitViewComponent } from '@components/split-view/split-view'; @@ -31,7 +31,6 @@ import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-lin import { CoreTimeUtils } from '@services/utils/time'; import { AddonNotificationsNotificationsSource } from '@addons/notifications/classes/notifications-source'; import { CoreListItemsManager } from '@classes/items-management/list-items-manager'; -import { AddonNotificationsNotificationToRender } from '@addons/notifications/services/notifications-helper'; import { AddonLegacyNotificationsNotificationsSource } from '@addons/notifications/classes/legacy-notifications-source'; /** @@ -45,7 +44,7 @@ import { AddonLegacyNotificationsNotificationsSource } from '@addons/notificatio export class AddonNotificationsListPage implements AfterViewInit, OnDestroy { @ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent; - notifications!: CoreListItemsManager; + notifications!: CoreListItemsManager; fetchMoreNotificationsFailed = false; canMarkAllNotificationsAsRead = false; loadingMarkAllNotificationsAsRead = false; diff --git a/src/addons/notifications/pages/notification/notification.html b/src/addons/notifications/pages/notification/notification.html index 6c7f95dd6..808cfe861 100644 --- a/src/addons/notifications/pages/notification/notification.html +++ b/src/addons/notifications/pages/notification/notification.html @@ -10,40 +10,40 @@ -
+
- -
- + +
+
- -
- -
- + + +
+ +
- -

- +

-

{{ timecreated | coreTimeAgo }} · {{ - userFromFullName }} +

+ {{ notification.timecreated | coreTimeAgo }} + · {{ notification.userfromfullname }}

- + diff --git a/src/addons/notifications/pages/notification/notification.ts b/src/addons/notifications/pages/notification/notification.ts index eea8ff181..7a5b4edb8 100644 --- a/src/addons/notifications/pages/notification/notification.ts +++ b/src/addons/notifications/pages/notification/notification.ts @@ -14,10 +14,10 @@ import { AddonLegacyNotificationsNotificationsSource } from '@addons/notifications/classes/legacy-notifications-source'; import { AddonNotificationsNotificationsSource } from '@addons/notifications/classes/notifications-source'; -import { AddonNotificationsNotificationData } from '@addons/notifications/services/handlers/push-click'; +import { AddonNotificationsPushNotification } from '@addons/notifications/services/handlers/push-click'; +import { AddonNotifications, AddonNotificationsNotificationMessageFormatted } from '@addons/notifications/services/notifications'; import { AddonNotificationsHelper, - AddonNotificationsNotificationToRender, } from '@addons/notifications/services/notifications-helper'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRouteSnapshot } from '@angular/router'; @@ -39,21 +39,15 @@ import { CoreDomUtils } from '@services/utils/dom'; export class AddonNotificationsNotificationPage implements OnInit, OnDestroy { notifications?: AddonNotificationSwipeItemsManager; - subject = ''; // Notification subject. - content = ''; // Notification content. - userIdFrom = -1; // User ID who sent the notification. + notification?: AddonNotificationsNotificationMessageFormatted; profileImageUrlFrom?: string; // Avatar of the user who sent the notification. - userFromFullName?: string; // Name of the user who sent the notification. - iconUrl?: string; // Icon URL. - modname?: string; // Module name. loaded = false; - timecreated = 0; // Actions data. actions: CoreContentLinksAction[] = []; - contextUrl?: string; - courseId?: number; - actionsData?: Record; // Extra data to handle the URL. + protected contextUrl?: string; + protected courseId?: number; + protected actionsData?: Record; // Extra data to handle the URL. /** * @inheritdoc @@ -70,31 +64,11 @@ export class AddonNotificationsNotificationPage implements OnInit, OnDestroy { return; } - if ('subject' in notification) { - this.subject = notification.subject; - this.content = notification.mobiletext || notification.fullmessagehtml; - this.userIdFrom = notification.useridfrom; - this.profileImageUrlFrom = notification.profileimageurlfrom; - this.userFromFullName = notification.userfromfullname; - this.iconUrl = notification.iconurl; - if (notification.moodlecomponent?.startsWith('mod_') && notification.iconurl) { - const modname = notification.moodlecomponent.substring(4); - if (notification.iconurl.match('/theme/image.php/[^/]+/' + modname + '/[-0-9]*/') || - notification.iconurl.match('/theme/image.php/[^/]+/' + notification.moodlecomponent + '/[-0-9]*/')) { - this.modname = modname; - } - } - this.timecreated = notification.timecreated; - } else { - this.subject = notification.title || ''; - this.content = notification.message || ''; - this.userIdFrom = notification.userfromid ? Number(notification.userfromid) : -1; - this.profileImageUrlFrom = notification.senderImage; - this.userFromFullName = notification.userfromfullname; - this.timecreated = Number(notification.date ?? 0); - } + this.notification = 'subject' in notification ? + notification : + await AddonNotifications.convertPushToMessage(notification); - await this.loadActions(notification); + await this.loadActions(this.notification); AddonNotificationsHelper.markNotificationAsRead(notification); this.loaded = true; @@ -153,7 +127,7 @@ export class AddonNotificationsNotificationPage implements OnInit, OnDestroy { * @param notification Notification. * @returns Promise resolved when done. */ - async loadActions(notification: AddonNotificationsNotification): Promise { + async loadActions(notification: AddonNotificationsNotificationMessageFormatted): Promise { if (!notification.contexturl && (!notification.customdata || !notification.customdata.appurl)) { // No URL, nothing to do. return; @@ -161,7 +135,7 @@ export class AddonNotificationsNotificationPage implements OnInit, OnDestroy { let actions: CoreContentLinksAction[] = []; this.actionsData = notification.customdata; - this.contextUrl = notification.contexturl; + this.contextUrl = notification.contexturl || undefined; this.courseId = 'courseid' in notification ? notification.courseid : undefined; // Treat appurl first if any. @@ -231,4 +205,4 @@ class AddonNotificationSwipeItemsManager extends CoreSwipeNavigationItemsManager } -type AddonNotificationsNotification = AddonNotificationsNotificationToRender | AddonNotificationsNotificationData; +type AddonNotificationsNotification = AddonNotificationsNotificationMessageFormatted | AddonNotificationsPushNotification; diff --git a/src/addons/notifications/services/handlers/push-click.ts b/src/addons/notifications/services/handlers/push-click.ts index 197ac86b8..8354de06a 100644 --- a/src/addons/notifications/services/handlers/push-click.ts +++ b/src/addons/notifications/services/handlers/push-click.ts @@ -41,7 +41,7 @@ export class AddonNotificationsPushClickHandlerService implements CorePushNotifi * @param notification The notification to check. * @returns Whether the notification click is handled by this handler */ - async handles(notification: AddonNotificationsNotificationData): Promise { + async handles(notification: AddonNotificationsPushNotification): Promise { if (!notification.moodlecomponent) { // The notification doesn't come from Moodle. Handle it. return true; @@ -63,7 +63,7 @@ export class AddonNotificationsPushClickHandlerService implements CorePushNotifi * @param notification Notification to mark. * @returns Promise resolved when done. */ - protected async markAsRead(notification: AddonNotificationsNotificationData): Promise { + protected async markAsRead(notification: AddonNotificationsPushNotification): Promise { await CoreUtils.ignoreErrors(AddonNotificationsHelper.markNotificationAsRead(notification)); } @@ -73,7 +73,7 @@ export class AddonNotificationsPushClickHandlerService implements CorePushNotifi * @param notification The notification to check. * @returns Promise resolved when done. */ - async handleClick(notification: AddonNotificationsNotificationData): Promise { + async handleClick(notification: AddonNotificationsPushNotification): Promise { if (notification.customdata?.extendedtext) { // Display the text in a modal. @@ -137,7 +137,7 @@ export class AddonNotificationsPushClickHandlerService implements CorePushNotifi export const AddonNotificationsPushClickHandler = makeSingleton(AddonNotificationsPushClickHandlerService); -export type AddonNotificationsNotificationData = CorePushNotificationsNotificationBasicData & { +export type AddonNotificationsPushNotification = CorePushNotificationsNotificationBasicData & { contexturl?: string; // URL related to the notification. savedmessageid?: number; // Notification ID (optional). id?: number; // Notification ID (optional). diff --git a/src/addons/notifications/services/notifications-helper.ts b/src/addons/notifications/services/notifications-helper.ts index 6dec099d1..e03c2b10c 100644 --- a/src/addons/notifications/services/notifications-helper.ts +++ b/src/addons/notifications/services/notifications-helper.ts @@ -28,7 +28,7 @@ import { AddonNotificationsProvider, } from './notifications'; import { CoreEvents } from '@singletons/events'; -import { AddonNotificationsNotificationData } from './handlers/push-click'; +import { AddonNotificationsPushNotification } from './handlers/push-click'; import { CoreTimeUtils } from '@services/utils/time'; /** @@ -42,23 +42,12 @@ export class AddonNotificationsHelperProvider { * * @param notification The notification object. * @returns The notification formatted to render. + * @deprecated since 4.2. This function isn't needed anymore. */ formatNotificationText( notification: AddonNotificationsNotificationMessageFormatted, - ): AddonNotificationsNotificationToRender { - const formattedNotification: AddonNotificationsNotificationToRender = notification; - - if (notification.moodlecomponent?.startsWith('mod_') && notification.iconurl) { - const modname = notification.moodlecomponent.substring(4); - if (notification.iconurl.match('/theme/image.php/[^/]+/' + modname + '/[-0-9]*/') || - notification.iconurl.match('/theme/image.php/[^/]+/' + notification.moodlecomponent + '/[-0-9]*/')) { - formattedNotification.modname = modname; - } - } else { - formattedNotification.iconurl = formattedNotification.iconurl || undefined; // Make sure the property exists. - } - - return formattedNotification; + ): AddonNotificationsNotificationMessageFormatted { + return notification; } /** @@ -128,7 +117,7 @@ export class AddonNotificationsHelperProvider { * @returns Promise resolved when done. */ async markNotificationAsRead( - notification: AddonNotificationsNotificationMessageFormatted | AddonNotificationsNotificationData, + notification: AddonNotificationsNotificationMessageFormatted | AddonNotificationsPushNotification, siteId?: string, ): Promise { if ('read' in notification && (notification.read || notification.timeread > 0)) { @@ -197,11 +186,3 @@ type AddonNotificationsPreferencesNotificationProcessorFormatted = AddonNotifica export type AddonNotificationsPreferencesProcessorFormatted = AddonNotificationsPreferencesProcessor & { supported?: boolean; // Calculated in the app. Whether the processor is supported in the app. }; - -/** - * Notification with some calculated data to render it. - */ -export type AddonNotificationsNotificationToRender = AddonNotificationsNotificationMessageFormatted & { - iconurl?: string; - modname?: string; -}; diff --git a/src/addons/notifications/services/notifications.ts b/src/addons/notifications/services/notifications.ts index 3e7e3f715..83ddd8b4d 100644 --- a/src/addons/notifications/services/notifications.ts +++ b/src/addons/notifications/services/notifications.ts @@ -18,11 +18,12 @@ import { CoreSites, CoreSitesCommonWSOptions } from '@services/sites'; import { CoreWSExternalWarning } from '@services/ws'; import { CoreTextUtils } from '@services/utils/text'; import { CoreTimeUtils } from '@services/utils/time'; -import { CoreUser } from '@features/user/services/user'; +import { CoreUser, USER_NOREPLY_USER } from '@features/user/services/user'; import { CoreSite, CoreSiteWSPreSets } from '@classes/site'; import { CoreLogger } from '@singletons/logger'; -import { makeSingleton } from '@singletons'; +import { Translate, makeSingleton } from '@singletons'; import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; +import { AddonNotificationsPushNotification } from './handlers/push-click'; declare module '@singletons/events' { @@ -56,6 +57,48 @@ export class AddonNotificationsProvider { this.logger = CoreLogger.getInstance('AddonNotificationsProvider'); } + /** + * Convert a push notification data to use the same format as the get_messages WS. + * + * @param notification Push notification to convert. + * @returns Converted notification. + */ + async convertPushToMessage( + notification: AddonNotificationsPushNotification, + ): Promise { + const message = notification.message ?? ''; + const siteInfo = CoreSites.getCurrentSite()?.getInfo(); + + if (notification.senderImage && notification.customdata && !notification.customdata.notificationiconurl) { + notification.customdata.notificationiconurl = notification.senderImage; + } + + const notificationMessage: AddonNotificationsNotificationMessage = { + id: notification.id ?? 0, + useridfrom: notification.userfromid ? Number(notification.userfromid) : USER_NOREPLY_USER, + userfromfullname: notification.userfromfullname ?? Translate.instant('core.noreplyname'), + useridto: notification.usertoid ? Number(notification.usertoid) : (siteInfo?.userid ?? 0), + usertofullname: siteInfo?.fullname ?? '', + subject: notification.title ?? '', + text: message, + fullmessage: message, + fullmessageformat: 1, + fullmessagehtml: message, + smallmessage: message, + notification: Number(notification.notif ?? 1), + contexturl: notification.contexturl || null, + contexturlname: null, + timecreated: Number(notification.date ?? 0), + timeread: 0, + component: notification.moodlecomponent, + customdata: notification.customdata ? JSON.stringify(notification.customdata) : undefined, + }; + + const formatted = await this.formatNotificationsData([notificationMessage]); + + return formatted[0]; + } + /** * Function to format notification data. * @@ -76,7 +119,7 @@ export class AddonNotificationsProvider { notification.read = notification.timeread > 0; if (typeof notification.customdata == 'string') { - notification.customdata = CoreTextUtils.parseJSON>(notification.customdata, {}); + notification.customdata = CoreTextUtils.parseJSON>(notification.customdata, {}); } // Try to set courseid the notification belongs to. @@ -91,13 +134,16 @@ export class AddonNotificationsProvider { if (!notification.iconurl) { // The iconurl is only returned in 4.0 or above. Calculate it if not present. - if (notification.component && notification.component.startsWith('mod_')) { + if (notification.moodlecomponent && notification.moodlecomponent.startsWith('mod_')) { notification.iconurl = await CoreCourseModuleDelegate.getModuleIconSrc( - notification.component.replace('mod_', ''), + notification.moodlecomponent.replace('mod_', ''), ); } } + const imgUrl = notification.customdata?.notificationpictureurl || notification.customdata?.notificationiconurl; + notification.imgUrl = imgUrl ? String(imgUrl) : undefined; + if (notification.useridfrom > 0) { // Try to get the profile picture of the user. try { @@ -502,8 +548,8 @@ export type AddonNotificationsNotificationMessage = { fullmessagehtml: string; // The message in html. smallmessage: string; // The shorten message. notification: number; // Is a notification?. - contexturl: string; // Context URL. - contexturlname: string; // Context URL link name. + contexturl: string | null; // Context URL. + contexturlname: string | null; // Context URL link name. timecreated: number; // Time created. timeread: number; // Time read. usertofullname: string; // User to full name. @@ -532,15 +578,16 @@ export type AddonNotificationsGetUserNotificationPreferencesResult = { * Calculated data for messages returned by core_message_get_messages. */ export type AddonNotificationsNotificationCalculatedData = { - mobiletext?: string; // Calculated in the app. Text to display for the notification. + mobiletext: string; // Calculated in the app. Text to display for the notification. moodlecomponent?: string; // Calculated in the app. Moodle's component. - notif?: number; // Calculated in the app. Whether it's a notification. - notification?: number; // Calculated in the app in some cases. Whether it's a notification. - read?: boolean; // Calculated in the app. Whether the notifications is read. + notif: number; // Calculated in the app. Whether it's a notification. + notification: number; // Calculated in the app in some cases. Whether it's a notification. + read: boolean; // Calculated in the app. Whether the notifications is read. courseid?: number; // Calculated in the app. Course the notification belongs to. profileimageurlfrom?: string; // Calculated in the app. Avatar of user that sent the notification. userfromfullname?: string; // Calculated in the app in some cases. User from full name. - customdata?: Record; // Parsed custom data. + customdata?: Record; // Parsed custom data. + imgUrl?: string; // Calculated in the app. URL of the image to use if the notification has no real user from. }; /** diff --git a/src/core/features/pushnotifications/services/pushnotifications.ts b/src/core/features/pushnotifications/services/pushnotifications.ts index 3f2ee4734..eb8fca182 100644 --- a/src/core/features/pushnotifications/services/pushnotifications.ts +++ b/src/core/features/pushnotifications/services/pushnotifications.ts @@ -460,7 +460,7 @@ export class CorePushNotificationsProvider { title: notification.title, message: notification.message, customdata: typeof rawData.customdata == 'string' ? - CoreTextUtils.parseJSON>(rawData.customdata, {}) : rawData.customdata, + CoreTextUtils.parseJSON>(rawData.customdata, {}) : rawData.customdata, }); let site: CoreSite | undefined; @@ -964,7 +964,7 @@ export type CorePushNotificationsNotificationBasicRawData = { export type CorePushNotificationsNotificationBasicData = Omit & { title?: string; // Notification title. message?: string; // Notification message. - customdata?: Record; // Parsed custom data. + customdata?: Record; // Parsed custom data. }; /** diff --git a/src/core/features/user/services/user.ts b/src/core/features/user/services/user.ts index 3e9ca4b0f..7484e800b 100644 --- a/src/core/features/user/services/user.ts +++ b/src/core/features/user/services/user.ts @@ -59,6 +59,11 @@ export const USER_PROFILE_PICTURE_UPDATED = 'CoreUserProfilePictureUpdated'; */ export const USER_PROFILE_SERVER_TIMEZONE = '99'; +/** + * Fake ID for a "no reply" user. + */ +export const USER_NOREPLY_USER = -10; + /** * Service to provide user functionalities. */ diff --git a/src/core/lang.json b/src/core/lang.json index 913cf4c2f..6897372a9 100644 --- a/src/core/lang.json +++ b/src/core/lang.json @@ -216,6 +216,7 @@ "nopermissionerror": "Sorry, but you do not currently have permissions to do that", "nopermissions": "Sorry, but you do not currently have permissions to do that ({{$a}}).", "nopermissiontoaccesspage": "You don't have permission to access this page.", + "noreplyname": "Do not reply to this email", "noresults": "No results", "noselection": "No selection", "notapplicable": "n/a",