diff --git a/src/addons/calendar/pages/index/index.ts b/src/addons/calendar/pages/index/index.ts index ac6828c74..0943286ae 100644 --- a/src/addons/calendar/pages/index/index.ts +++ b/src/addons/calendar/pages/index/index.ts @@ -159,7 +159,7 @@ export class AddonCalendarIndexPage implements OnInit, OnDestroy { } /** - * View loaded. + * @inheritdoc */ ngOnInit(): void { this.loadUpcoming = !!CoreNavigator.getRouteBooleanParam('upcoming'); diff --git a/src/addons/messages/pages/discussion/discussion.ts b/src/addons/messages/pages/discussion/discussion.ts index 44ec23ea9..fe11d4c22 100644 --- a/src/addons/messages/pages/discussion/discussion.ts +++ b/src/addons/messages/pages/discussion/discussion.ts @@ -25,6 +25,7 @@ import { AddonMessages, AddonMessagesConversationMessageFormatted, AddonMessagesSendMessageResults, + AddonMessagesUpdateConversationAction, } from '../../services/messages'; import { AddonMessagesOffline, AddonMessagesOfflineMessagesDBRecordFormatted } from '../../services/messages-offline'; import { AddonMessagesSync, AddonMessagesSyncProvider } from '../../services/messages-sync'; @@ -1298,7 +1299,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView CoreEvents.trigger(AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, { conversationId: this.conversation.id, - action: 'favourite', + action: AddonMessagesUpdateConversationAction.FAVOURITE, value: this.conversation.isfavourite, }, this.siteId); } catch (error) { @@ -1330,7 +1331,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView CoreEvents.trigger(AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, { conversationId: this.conversation.id, - action: 'mute', + action: AddonMessagesUpdateConversationAction.MUTE, value: this.conversation.ismuted, }, this.siteId); @@ -1446,7 +1447,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, { conversationId: this.conversation.id, - action: 'delete', + action: AddonMessagesUpdateConversationAction.DELETE, }, this.siteId, ); diff --git a/src/addons/messages/pages/group-conversations/group-conversations.html b/src/addons/messages/pages/group-conversations/group-conversations.html index 313ebb0b5..145d43b60 100644 --- a/src/addons/messages/pages/group-conversations/group-conversations.html +++ b/src/addons/messages/pages/group-conversations/group-conversations.html @@ -21,7 +21,7 @@ - + @@ -30,110 +30,46 @@ - - - -
- - - - - -

{{ 'addon.messages.nofavourites' | translate }}

-
-
-
- - - - - - - - - -
- - - - - -

{{ 'addon.messages.nogroupconversations' | translate }}

-
-
-
- - - - - - - - -
- - - - - -

{{ 'addon.messages.noindividualconversations' | translate }}

-
-
-
- - - - - - + + + + +

{{ option.titleString | translate }} ({{ option.count }})

+
+ + {{ option.unread }} + +
+
+ + + + + + +

{{ option.emptyString| translate }}

+
+
+
+ + + + + +
+
+
diff --git a/src/addons/messages/pages/group-conversations/group-conversations.ts b/src/addons/messages/pages/group-conversations/group-conversations.ts index c27a34d7d..20fbedc11 100644 --- a/src/addons/messages/pages/group-conversations/group-conversations.ts +++ b/src/addons/messages/pages/group-conversations/group-conversations.ts @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core'; -import { IonContent } from '@ionic/angular'; +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { AccordionGroupChangeEventDetail, IonAccordionGroup, IonContent } from '@ionic/angular'; import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreSites } from '@services/sites'; import { @@ -21,6 +21,8 @@ import { AddonMessagesConversationFormatted, AddonMessages, AddonMessagesNewMessagedEventData, + AddonMessagesUnreadConversationCountsEventData, + AddonMessagesUpdateConversationAction, } from '../../services/messages'; import { AddonMessagesOffline, @@ -40,6 +42,12 @@ import { CoreMainMenuDeepLinkManager } from '@features/mainmenu/classes/deep-lin import { CorePlatform } from '@services/platform'; import { CoreSplitViewComponent } from '@components/split-view/split-view'; +const enum AddonMessagesGroupConversationOptionNames { + FAVOURITES = 'favourites', + GROUP = 'group', + INDIVIDUAL = 'individual', +} + /** * Page that displays the list of conversations, including group conversations. */ @@ -51,43 +59,49 @@ import { CoreSplitViewComponent } from '@components/split-view/split-view'; export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { @ViewChild(CoreSplitViewComponent) splitView!: CoreSplitViewComponent; - @ViewChild(IonContent) content?: IonContent; - @ViewChild('favlist') favListEl?: ElementRef; - @ViewChild('grouplist') groupListEl?: ElementRef; - @ViewChild('indlist') indListEl?: ElementRef; + @ViewChild('accordionGroup', { static: true }) accordionGroup!: IonAccordionGroup; loaded = false; loadingMessage: string; selectedConversationId?: number; selectedUserId?: number; contactRequestsCount = 0; - favourites: AddonMessagesGroupConversationOption = { - type: undefined, - favourites: true, - count: 0, - unread: 0, - conversations: [], - }; - group: AddonMessagesGroupConversationOption = { - type: AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP, - favourites: false, - count: 0, - unread: 0, - conversations: [], - }; - - individual: AddonMessagesGroupConversationOption = { - type: AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, - favourites: false, - count: 0, - unread: 0, - conversations: [], - }; + groupConversations: AddonMessagesGroupConversationOption[] = [ + { + optionName: AddonMessagesGroupConversationOptionNames.FAVOURITES, + titleString: 'core.favourites', + emptyString: 'addon.messages.nofavourites', + type: undefined, + favourites: true, + count: 0, + unread: 0, + conversations: [], + }, + { + optionName: AddonMessagesGroupConversationOptionNames.GROUP, + titleString: 'addon.messages.groupconversations', + emptyString: 'addon.messages.nogroupconversations', + type: AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP, + favourites: false, + count: 0, + unread: 0, + conversations: [], + }, + { + optionName: AddonMessagesGroupConversationOptionNames.INDIVIDUAL, + titleString: 'addon.messages.individualconversations', + emptyString: 'addon.messages.noindividualconversations', + type: AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, + favourites: false, + count: 0, + unread: 0, + conversations: [], + }, + ]; typeGroup = AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP; - currentListEl?: HTMLElement; protected siteId: string; protected currentUserId: number; @@ -100,6 +114,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { protected updateConversationListObserver: CoreEventObserver; protected contactRequestsCountObserver: CoreEventObserver; protected memberInfoObserver: CoreEventObserver; + protected firstExpand = false; constructor( protected route: ActivatedRoute, @@ -114,9 +129,9 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { (data) => { // Check if the new message belongs to the option that is currently expanded. const expandedOption = this.getExpandedOption(); - const messageOption = this.getConversationOption(data); + const messageOptionName = this.getConversationOptionName(data); - if (expandedOption != messageOption) { + if (expandedOption?.optionName !== messageOptionName) { return; // Message doesn't belong to current list, stop. } @@ -155,8 +170,9 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { } // Sort the affected list. - const option = this.getConversationOption(conversation); - option.conversations = AddonMessages.sortConversations(option.conversations || []); + const optionName = this.getConversationOptionName(conversation); + const option = this.getConversationGroupByName(optionName); + option.conversations = AddonMessages.sortConversations(option.conversations); if (isNewer) { // The last message is newer than the previous one, scroll to top to keep viewing the conversation. @@ -209,11 +225,11 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { this.updateConversationListObserver = CoreEvents.on( AddonMessagesProvider.UPDATE_CONVERSATION_LIST_EVENT, (data) => { - if (data && data.action == 'mute') { - // If the conversation is displayed, change its muted value. + if (data?.action === AddonMessagesUpdateConversationAction.MUTE) { + // If the conversation is displayed, change its muted value. const expandedOption = this.getExpandedOption(); - if (expandedOption && expandedOption.conversations) { + if (expandedOption?.conversations) { const conversation = this.findConversation(data.conversationId, undefined, expandedOption); if (conversation) { conversation.ismuted = !!data.value; @@ -233,7 +249,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { this.pushObserver = CorePushNotificationsDelegate.on('receive') .subscribe((notification) => { // New message received. If it's from current site, refresh the data. - if (CoreUtils.isFalseOrZero(notification.notif) && notification.site == this.siteId) { + if (CoreUtils.isFalseOrZero(notification.notif) && notification.site === this.siteId) { // Don't refresh unread counts, it's refreshed from the main menu handler in this case. this.refreshData(undefined, false); } @@ -243,9 +259,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { this.cronObserver = CoreEvents.on( AddonMessagesProvider.UNREAD_CONVERSATION_COUNTS_EVENT, (data) => { - this.favourites.unread = data.favourites; - this.individual.unread = data.individual + data.self; // Self is only returned if it's not favourite. - this.group.unread = data.group; + this.setCounts(data, 'unread'); }, this.siteId, ); @@ -269,15 +283,14 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { } const expandedOption = this.getExpandedOption(); - if (expandedOption == this.individual || expandedOption == this.favourites) { - if (!expandedOption.conversations || expandedOption.conversations.length <= 0) { - return; - } + if (expandedOption?.optionName === AddonMessagesGroupConversationOptionNames.GROUP || + !expandedOption?.conversations.length) { + return; + } - const conversation = this.findConversation(undefined, data.userId, expandedOption); - if (conversation) { - conversation.isblocked = data.userBlocked; - } + const conversation = this.findConversation(undefined, data.userId, expandedOption); + if (conversation) { + conversation.isblocked = data.userBlocked; } }, this.siteId, @@ -285,7 +298,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { } /** - * Component loaded. + * @inheritdoc */ async ngOnInit(): Promise { this.route.queryParams.subscribe(async (params) => { @@ -305,15 +318,11 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { if (!this.selectedConversationId && !this.selectedUserId && CoreScreen.isTablet) { // Load the first conversation. - let conversation: AddonMessagesConversationForList; const expandedOption = this.getExpandedOption(); - if (expandedOption && expandedOption.conversations.length) { - conversation = expandedOption.conversations[0]; - - if (conversation) { - await this.gotoConversation(conversation.id); - } + const conversation = expandedOption?.conversations[0]; + if (conversation) { + await this.gotoConversation(conversation.id); } } @@ -341,22 +350,19 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { try { await Promise.all(promises); - // The expanded status hasn't been initialized. Do it now. - if (this.favourites.expanded === undefined && (this.selectedConversationId || this.selectedUserId)) { + if (!this.firstExpand && (this.selectedConversationId || this.selectedUserId)) { // A certain conversation should be opened. // We don't know which option it belongs to, so we need to fetch the data for all of them. - const promises: Promise[] = []; - - promises.push(this.fetchDataForOption(this.favourites, false)); - promises.push(this.fetchDataForOption(this.group, false)); - promises.push(this.fetchDataForOption(this.individual, false)); + const promises = this.groupConversations.map((option) => + this.fetchDataForOption(option, false)); await Promise.all(promises); // All conversations have been loaded, find the one we need to load and expand its option. const conversation = this.findConversation(this.selectedConversationId, this.selectedUserId); if (conversation) { - const option = this.getConversationOption(conversation); + const optionName = this.getConversationOptionName(conversation); + const option = this.getConversationGroupByName(optionName); await this.expandOption(option); @@ -376,18 +382,24 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { /** * Fetch data for the expanded option. - * - * @returns Promise resolved when done. */ protected async fetchDataForExpandedOption(): Promise { - if (this.favourites.expanded === undefined) { + if (!this.firstExpand) { // Calculate which option should be expanded initially. - this.favourites.expanded = this.favourites.count != 0 && !this.group.unread && !this.individual.unread; - this.group.expanded = !this.favourites.expanded && this.group.count != 0 && !this.individual.unread; - this.individual.expanded = !this.favourites.expanded && !this.group.expanded; - } + let expandOption = this.groupConversations.find((option) => option.unread); - this.loadCurrentListElement(); + if (!expandOption) { + expandOption = this.groupConversations.find((option) => option.count > 0); + } + + if (!expandOption) { + expandOption = this.getConversationGroupByName(AddonMessagesGroupConversationOptionNames.INDIVIDUAL); + } + + this.accordionGroup.value = expandOption.optionName; + + this.firstExpand = true; + } const expandedOption = this.getExpandedOption(); @@ -418,8 +430,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { conversations: [], canLoadMore: false, }; - let offlineMessages: - AddonMessagesOfflineAnyMessagesFormatted[] = []; + let offlineMessages: AddonMessagesOfflineAnyMessagesFormatted[] = []; // Get the conversations and, if needed, the offline messages. Always try to get the latest data. promises.push(AddonMessages.invalidateConversations(this.siteId).then(async () => { @@ -469,9 +480,36 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { await AddonMessages.invalidateConversationCounts(this.siteId); const counts = await AddonMessages.getConversationCounts(this.siteId); - this.favourites.count = counts.favourites; - this.individual.count = counts.individual + counts.self; // Self is only returned if it's not favourite. - this.group.count = counts.group; + this.setCounts(counts); + } + + /** + * Set conversation counts. + * + * @param counts Counts to set. + * @param valueToSet Value to set count or unread. + */ + protected setCounts( + counts: AddonMessagesUnreadConversationCountsEventData, + valueToSet: 'count' | 'unread' = 'count', + ): void { + this.getConversationGroupByName(AddonMessagesGroupConversationOptionNames.FAVOURITES)[valueToSet] = counts.favourites; + this.getConversationGroupByName(AddonMessagesGroupConversationOptionNames.INDIVIDUAL)[valueToSet] = + counts.individual + counts.self; // Self is only returned if it's not favourite. + this.getConversationGroupByName(AddonMessagesGroupConversationOptionNames.GROUP)[valueToSet] = counts.group; + } + + /** + * Get a conversation group by its name. + * + * @param name Name of the group. + * @returns The conversation group. + */ + protected getConversationGroupByName(name: AddonMessagesGroupConversationOptionNames): AddonMessagesGroupConversationOption { + const option = this.groupConversations.find((group) => group.optionName === name); + + // Option should always be defined. + return option ?? this.groupConversations[0]; } /** @@ -491,16 +529,19 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { if (conversationId) { const conversations: AddonMessagesConversationForList[] = option ? option.conversations - : (this.favourites.conversations.concat(this.group.conversations).concat(this.individual.conversations)); + : this.groupConversations.flatMap((option) => option.conversations); - return conversations.find((conv) => conv.id == conversationId); + return conversations.find((conv) => conv.id === conversationId); } - const conversations = option - ? option.conversations - : this.favourites.conversations.concat(this.individual.conversations); + let conversations = option?.conversations; + if (!conversations) { + // Only check on favourites and individual conversations. + conversations = this.getConversationGroupByName(AddonMessagesGroupConversationOptionNames.FAVOURITES).conversations + .concat(this.getConversationGroupByName(AddonMessagesGroupConversationOptionNames.INDIVIDUAL).conversations); + } - return conversations.find((conv) => conv.userid == userId); + return conversations.find((conv) => conv.userid === userId); } /** @@ -509,12 +550,8 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { * @returns Option currently expanded. */ protected getExpandedOption(): AddonMessagesGroupConversationOption | undefined { - if (this.favourites.expanded) { - return this.favourites; - } else if (this.group.expanded) { - return this.group; - } else if (this.individual.expanded) { - return this.individual; + if (this.accordionGroup.value) { + return this.getConversationGroupByName(this.accordionGroup.value as AddonMessagesGroupConversationOptionNames); } } @@ -572,7 +609,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { option.loadMoreError = true; } - infiniteComplete && infiniteComplete(); + infiniteComplete?.(); } /** @@ -617,13 +654,13 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { imageurl: message.conversation?.imageurl || '', }; - if (this.getConversationOption(conversation) == option) { + if (this.getConversationOptionName(conversation) === option.optionName) { // Message belongs to current option, add the conversation. this.addLastOfflineMessage(conversation, message); - this.addOfflineConversation(conversation); + this.addOfflineConversation(conversation, option); } } - } else if (option.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) { + } else if (option.type === AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) { // 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); @@ -655,7 +692,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { }; this.addLastOfflineMessage(conversation, message); - this.addOfflineConversation(conversation); + this.addOfflineConversation(conversation, option); return; })); @@ -670,9 +707,12 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { * Add an offline conversation into the right list of conversations. * * @param conversation Offline conversation to add. + * @param option Option where to add the conversation. */ - protected addOfflineConversation(conversation: AddonMessagesConversationForList): void { - const option = this.getConversationOption(conversation); + protected addOfflineConversation( + conversation: AddonMessagesConversationForList, + option: AddonMessagesGroupConversationOption, + ): void { option.conversations.unshift(conversation); } @@ -693,23 +733,23 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { } /** - * Given a conversation, return its option (favourites, group, individual). + * Given a conversation, return its option name. * * @param conversation Conversation to check. - * @returns Option object. + * @returns Option name. */ - protected getConversationOption( + protected getConversationOptionName( conversation: AddonMessagesConversationForList | AddonMessagesNewMessagedEventData, - ): AddonMessagesGroupConversationOption { + ): AddonMessagesGroupConversationOptionNames { if (conversation.isfavourite) { - return this.favourites; + return AddonMessagesGroupConversationOptionNames.FAVOURITES; } - if (conversation.type == AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP) { - return this.group; + if (conversation.type === AddonMessagesProvider.MESSAGE_CONVERSATION_TYPE_GROUP) { + return AddonMessagesGroupConversationOptionNames.GROUP; } - return this.individual; + return AddonMessagesGroupConversationOptionNames.INDIVIDUAL; } /** @@ -727,9 +767,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { try { await this.fetchData(refreshUnreadCounts); } finally { - if (refresher) { - refresher?.complete(); - } + refresher?.complete(); } } } @@ -737,19 +775,20 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { /** * Toogle the visibility of an option (expand/collapse). * - * @param option The option to expand/collapse. + * @param ev The event of the accordion. */ - toggle(option: AddonMessagesGroupConversationOption): void { - if (option.expanded) { - // Already expanded, close it. - option.expanded = false; - this.loadCurrentListElement(); - } else { - // Pass getCounts=true to update the counts everytime the user expands an option. - this.expandOption(option, true).catch((error) => { - CoreDomUtils.showErrorModalDefault(error, 'addon.messages.errorwhileretrievingdiscussions', true); - }); + accordionGroupChange(ev: AccordionGroupChangeEventDetail): void { + const optionName = ev.value as AddonMessagesGroupConversationOptionNames; + if (!optionName) { + return; } + + const option = this.getConversationGroupByName(optionName); + + // Pass getCounts=true to update the counts everytime the user expands an option. + this.expandOption(option, true).catch((error) => { + CoreDomUtils.showErrorModalDefault(error, 'addon.messages.errorwhileretrievingdiscussions', true); + }); } /** @@ -761,40 +800,18 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { */ protected async expandOption(option: AddonMessagesGroupConversationOption, getCounts = false): Promise { // Collapse all and expand the right one. - this.favourites.expanded = false; - this.group.expanded = false; - this.individual.expanded = false; - - option.expanded = true; option.loading = true; + this.accordionGroup.value = option.optionName; try { await this.fetchDataForOption(option, false, getCounts); - - this.loadCurrentListElement(); } catch (error) { - option.expanded = false; + this.accordionGroup.value = undefined; throw error; } finally { option.loading = false; } - - } - - /** - * Load the current list element based on the expanded list. - */ - protected loadCurrentListElement(): void { - if (this.favourites.expanded) { - this.currentListEl = this.favListEl && this.favListEl.nativeElement; - } else if (this.group.expanded) { - this.currentListEl = this.groupListEl && this.groupListEl.nativeElement; - } else if (this.individual.expanded) { - this.currentListEl = this.indListEl && this.indListEl.nativeElement; - } else { - this.currentListEl = undefined; - } } /** @@ -805,7 +822,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { } /** - * Page destroyed. + * @inheritdoc */ ngOnDestroy(): void { this.newMessagesObserver?.off(); @@ -825,11 +842,13 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { * Conversation options. */ export type AddonMessagesGroupConversationOption = { + optionName: AddonMessagesGroupConversationOptionNames; + titleString: string; + emptyString: string; type?: number; // Option type. favourites: boolean; // Whether it contains favourites conversations. count: number; // Number of conversations. unread?: number; // Number of unread conversations. - expanded?: boolean; // Whether the option is currently expanded. loading?: boolean; // Whether the option is being loaded. canLoadMore?: boolean; // Whether it can load more data. loadMoreError?: boolean; // Whether there was an error loading more conversations. diff --git a/src/addons/messages/services/messages.ts b/src/addons/messages/services/messages.ts index 158756a45..f95558d21 100644 --- a/src/addons/messages/services/messages.ts +++ b/src/addons/messages/services/messages.ts @@ -35,8 +35,6 @@ import { CoreWSError } from '@classes/errors/wserror'; import { AddonNotificationsPreferencesNotificationProcessorState } from '@addons/notifications/services/notifications'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; -const ROOT_CACHE_KEY = 'mmaMessages:'; - declare module '@singletons/events' { /** @@ -57,12 +55,20 @@ declare module '@singletons/events' { } +export const enum AddonMessagesUpdateConversationAction { + MUTE = 'mute', + FAVOURITE = 'favourite', + DELETE = 'delete', +} + /** * Service to handle messages. */ @Injectable({ providedIn: 'root' }) export class AddonMessagesProvider { + 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'; static readonly OPEN_CONVERSATION_EVENT = 'addon_messages_open_conversation_event'; // Notify a conversation should be opened. @@ -396,7 +402,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForBlockedContacts(userId: number): string { - return ROOT_CACHE_KEY + 'blockedContacts:' + userId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'blockedContacts:' + userId; } /** @@ -405,7 +411,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForContacts(): string { - return ROOT_CACHE_KEY + 'contacts'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'contacts'; } /** @@ -414,7 +420,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForUserContacts(): string { - return ROOT_CACHE_KEY + 'userContacts'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'userContacts'; } /** @@ -423,7 +429,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForContactRequests(): string { - return ROOT_CACHE_KEY + 'contactRequests'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'contactRequests'; } /** @@ -432,7 +438,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForContactRequestsCount(): string { - return ROOT_CACHE_KEY + 'contactRequestsCount'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'contactRequestsCount'; } /** @@ -442,7 +448,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ getCacheKeyForDiscussion(userId: number): string { - return ROOT_CACHE_KEY + 'discussion:' + userId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'discussion:' + userId; } /** @@ -452,7 +458,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForMessageCount(userId: number): string { - return ROOT_CACHE_KEY + 'count:' + userId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'count:' + userId; } /** @@ -461,7 +467,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForUnreadConversationCounts(): string { - return ROOT_CACHE_KEY + 'unreadConversationCounts'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'unreadConversationCounts'; } /** @@ -470,7 +476,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForDiscussions(): string { - return ROOT_CACHE_KEY + 'discussions'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'discussions'; } /** @@ -481,7 +487,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForConversation(userId: number, conversationId: number): string { - return ROOT_CACHE_KEY + 'conversation:' + userId + ':' + conversationId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'conversation:' + userId + ':' + conversationId; } /** @@ -492,7 +498,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForConversationBetweenUsers(userId: number, otherUserId: number): string { - return ROOT_CACHE_KEY + 'conversationBetweenUsers:' + userId + ':' + otherUserId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'conversationBetweenUsers:' + userId + ':' + otherUserId; } /** @@ -503,7 +509,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForConversationMembers(userId: number, conversationId: number): string { - return ROOT_CACHE_KEY + 'conversationMembers:' + userId + ':' + conversationId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'conversationMembers:' + userId + ':' + conversationId; } /** @@ -514,7 +520,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForConversationMessages(userId: number, conversationId: number): string { - return ROOT_CACHE_KEY + 'conversationMessages:' + userId + ':' + conversationId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'conversationMessages:' + userId + ':' + conversationId; } /** @@ -535,7 +541,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForConversationCounts(): string { - return ROOT_CACHE_KEY + 'conversationCounts'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'conversationCounts'; } /** @@ -546,7 +552,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForMemberInfo(userId: number, otherUserId: number): string { - return ROOT_CACHE_KEY + 'memberInfo:' + userId + ':' + otherUserId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'memberInfo:' + userId + ':' + otherUserId; } /** @@ -556,7 +562,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getCacheKeyForSelfConversation(userId: number): string { - return ROOT_CACHE_KEY + 'selfconversation:' + userId; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'selfconversation:' + userId; } /** @@ -575,7 +581,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getRootCacheKeyForConversations(): string { - return ROOT_CACHE_KEY + 'conversations:'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'conversations:'; } /** @@ -1132,7 +1138,7 @@ export class AddonMessagesProvider { const result = await site.read( 'core_message_get_conversation_counts', - { }, + {}, preSets, ); @@ -1388,7 +1394,7 @@ export class AddonMessagesProvider { * @returns Cache key. */ protected getMessagePreferencesCacheKey(): string { - return ROOT_CACHE_KEY + 'messagePreferences'; + return AddonMessagesProvider.ROOT_CACHE_KEY + 'messagePreferences'; } /** @@ -2706,7 +2712,7 @@ export class AddonMessagesProvider { * @param conversations Array of conversations. * @returns Conversations sorted with most recent last. */ - sortConversations(conversations: AddonMessagesConversationFormatted[]): AddonMessagesConversationFormatted[] { + sortConversations(conversations: AddonMessagesConversationFormatted[] = []): AddonMessagesConversationFormatted[] { return conversations.sort((a, b) => { const timeA = Number(a.lastmessagedate); const timeB = Number(b.lastmessagedate); @@ -3684,7 +3690,7 @@ export type AddonMessagesNewMessagedEventData = { */ export type AddonMessagesUpdateConversationListEventData = { conversationId: number; - action: string; + action: AddonMessagesUpdateConversationAction; value?: boolean; }; diff --git a/src/addons/messages/tests/behat/snapshots/test-basic-usage-of-messages-in-app-view-recent-conversations-and-contacts_22.png b/src/addons/messages/tests/behat/snapshots/test-basic-usage-of-messages-in-app-view-recent-conversations-and-contacts_22.png index d6eada1dc..c4749d401 100644 Binary files a/src/addons/messages/tests/behat/snapshots/test-basic-usage-of-messages-in-app-view-recent-conversations-and-contacts_22.png and b/src/addons/messages/tests/behat/snapshots/test-basic-usage-of-messages-in-app-view-recent-conversations-and-contacts_22.png differ