From 44a39fd763706adfd874dd279ea73badd2a08438 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 22 Mar 2019 11:08:47 +0100 Subject: [PATCH 1/4] MOBILE-2927 notification: Use new notifications WS --- .../notifications/notifications.module.ts | 5 +- src/addon/notifications/pages/list/list.ts | 61 +++--------- src/addon/notifications/providers/helper.ts | 93 +++++++++++++++++++ .../notifications/providers/notifications.ts | 84 ++++++++++++++++- 4 files changed, 194 insertions(+), 49 deletions(-) create mode 100644 src/addon/notifications/providers/helper.ts diff --git a/src/addon/notifications/notifications.module.ts b/src/addon/notifications/notifications.module.ts index b19fd72dc..d5042b001 100644 --- a/src/addon/notifications/notifications.module.ts +++ b/src/addon/notifications/notifications.module.ts @@ -14,6 +14,7 @@ import { NgModule, NgZone } from '@angular/core'; import { AddonNotificationsProvider } from './providers/notifications'; +import { AddonNotificationsHelperProvider } from './providers/helper'; import { AddonNotificationsMainMenuHandler } from './providers/mainmenu-handler'; import { AddonNotificationsSettingsHandler } from './providers/settings-handler'; import { AddonNotificationsCronHandler } from './providers/cron-handler'; @@ -30,7 +31,8 @@ import { CorePushNotificationsDelegate } from '@core/pushnotifications/providers // List of providers (without handlers). export const ADDON_NOTIFICATIONS_PROVIDERS: any[] = [ - AddonNotificationsProvider + AddonNotificationsProvider, + AddonNotificationsHelperProvider ]; @NgModule({ @@ -40,6 +42,7 @@ export const ADDON_NOTIFICATIONS_PROVIDERS: any[] = [ ], providers: [ AddonNotificationsProvider, + AddonNotificationsHelperProvider, AddonNotificationsMainMenuHandler, AddonNotificationsSettingsHandler, AddonNotificationsCronHandler, diff --git a/src/addon/notifications/pages/list/list.ts b/src/addon/notifications/pages/list/list.ts index 2799cc8ee..3b8d1751a 100644 --- a/src/addon/notifications/pages/list/list.ts +++ b/src/addon/notifications/pages/list/list.ts @@ -21,6 +21,7 @@ import { CoreEventsProvider, CoreEventObserver } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { AddonNotificationsProvider } from '../../providers/notifications'; +import { AddonNotificationsHelperProvider } from '../../providers/helper'; import { CorePushNotificationsDelegate } from '@core/pushnotifications/providers/delegate'; /** @@ -40,15 +41,14 @@ export class AddonNotificationsListPage { canMarkAllNotificationsAsRead = false; loadingMarkAllNotificationsAsRead = false; - protected readCount = 0; - protected unreadCount = 0; protected cronObserver: CoreEventObserver; protected pushObserver: Subscription; constructor(navParams: NavParams, private domUtils: CoreDomUtilsProvider, private eventsProvider: CoreEventsProvider, private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider, private utils: CoreUtilsProvider, private notificationsProvider: AddonNotificationsProvider, - private pushNotificationsDelegate: CorePushNotificationsDelegate) { + private pushNotificationsDelegate: CorePushNotificationsDelegate, + private notificationsHelper: AddonNotificationsHelperProvider) { } /** @@ -79,53 +79,17 @@ export class AddonNotificationsListPage { protected fetchNotifications(refresh?: boolean): Promise { this.loadMoreError = false; - if (refresh) { - this.readCount = 0; - this.unreadCount = 0; - } + return this.notificationsHelper.getNotifications(refresh ? [] : this.notifications).then((result) => { + result.notifications.forEach(this.formatText.bind(this)); - const limit = AddonNotificationsProvider.LIST_LIMIT; - - return this.notificationsProvider.getUnreadNotifications(this.unreadCount, limit).then((unread) => { - const promises = []; - - unread.forEach(this.formatText.bind(this)); - - /* Don't add the unread notifications to this.notifications yet. If there are no unread notifications - that causes that the "There are no notifications" message is shown in pull to refresh. */ - this.unreadCount += unread.length; - - if (unread.length < limit) { - // Limit not reached. Get read notifications until reach the limit. - const readLimit = limit - unread.length; - promises.push(this.notificationsProvider.getReadNotifications(this.readCount, readLimit).then((read) => { - read.forEach(this.formatText.bind(this)); - this.readCount += read.length; - if (refresh) { - this.notifications = unread.concat(read); - } else { - this.notifications = this.notifications.concat(unread, read); - } - this.canLoadMore = read.length >= readLimit; - }).catch((error) => { - if (unread.length == 0) { - this.domUtils.showErrorModalDefault(error, 'addon.notifications.errorgetnotifications', true); - this.loadMoreError = true; // Set to prevent infinite calls with infinite-loading. - } - })); + if (refresh) { + this.notifications = result.notifications; } else { - if (refresh) { - this.notifications = unread; - } else { - this.notifications = this.notifications.concat(unread); - } - this.canLoadMore = true; + this.notifications = this.notifications.concat(result.notifications); } + this.canLoadMore = result.canLoadMore; - return Promise.all(promises).then(() => { - // Mark retrieved notifications as read if they are not. - this.markNotificationsAsRead(unread); - }); + this.markNotificationsAsRead(result.notifications); }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'addon.notifications.errorgetnotifications', true); this.loadMoreError = true; // Set to prevent infinite calls with infinite-loading. @@ -162,6 +126,11 @@ export class AddonNotificationsListPage { if (notifications.length > 0) { const promises = notifications.map((notification) => { + if (notification.read) { + // Already read, don't mark it. + return Promise.resolve(); + } + return this.notificationsProvider.markNotificationRead(notification.id); }); diff --git a/src/addon/notifications/providers/helper.ts b/src/addon/notifications/providers/helper.ts new file mode 100644 index 000000000..f9c9e80bf --- /dev/null +++ b/src/addon/notifications/providers/helper.ts @@ -0,0 +1,93 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// 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 { Injectable } from '@angular/core'; +import { CoreSitesProvider } from '@providers/sites'; +import { AddonNotificationsProvider } from './notifications'; + +/** + * Service that provides some helper functions for notifications. + */ +@Injectable() +export class AddonNotificationsHelperProvider { + + constructor(private notificationsProvider: AddonNotificationsProvider, private sitesProvider: CoreSitesProvider) { + } + + /** + * Get some notifications. It will try to use the new WS if available. + * + * @param {any[]} notifications Current list of loaded notifications. It's used to calculate the offset. + * @param {number} [limit] Number of notifications to get. Defaults to LIST_LIMIT. + * @param {boolean} [toDisplay=true] True if notifications will be displayed to the user, either in view or in a notification. + * @param {boolean} [forceCache] True if it should return cached data. Has priority over ignoreCache. + * @param {boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down). + * @param {string} [siteId] Site ID. If not defined, use current site. + * @return {Promise<{notifications: any[], canLoadMore: boolean}>} Promise resolved with notifications and if can load more. + */ + getNotifications(notifications: any[], limit?: number, toDisplay: boolean = true, forceCache?: boolean, ignoreCache?: boolean, + siteId?: string): Promise<{notifications: any[], canLoadMore: boolean}> { + + notifications = notifications || []; + limit = limit || AddonNotificationsProvider.LIST_LIMIT; + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + + return this.notificationsProvider.isPopupAvailable(siteId).then((available) => { + + if (available) { + return this.notificationsProvider.getPopupNotifications(notifications.length, limit, toDisplay, forceCache, + ignoreCache, siteId); + + } else { + // Fallback to get_messages. We need 2 calls, one for read and the other one for unread. + const unreadFrom = notifications.reduce((total, current) => { + return total + (current.read ? 0 : 1); + }, 0); + + return this.notificationsProvider.getUnreadNotifications(unreadFrom, limit, toDisplay, forceCache, ignoreCache, + siteId).then((unread) => { + + let promise; + + if (unread.length < limit) { + // Limit not reached. Get read notifications until reach the limit. + const readLimit = limit - unread.length, + readFrom = notifications.length - unreadFrom; + + promise = this.notificationsProvider.getReadNotifications(readFrom, readLimit, toDisplay, forceCache, + ignoreCache, siteId).then((read) => { + return unread.concat(read); + }).catch((error): any => { + if (unread.length > 0) { + // We were able to get some unread, return only the unread ones. + return unread; + } + + return Promise.reject(error); + }); + } else { + promise = Promise.resolve(unread); + } + + return promise.then((notifications) => { + return { + notifications: notifications, + canLoadMore: notifications.length >= limit + }; + }); + }); + } + }); + } +} diff --git a/src/addon/notifications/providers/notifications.ts b/src/addon/notifications/providers/notifications.ts index 1b9219fe8..b52578a53 100644 --- a/src/addon/notifications/providers/notifications.ts +++ b/src/addon/notifications/providers/notifications.ts @@ -45,9 +45,10 @@ export class AddonNotificationsProvider { * Function to format notification data. * * @param {any[]} notifications List of notifications. + * @param {boolean} [read] Whether the notifications are read or unread. * @return {Promise} Promise resolved with notifications. */ - protected formatNotificationsData(notifications: any[]): Promise { + protected formatNotificationsData(notifications: any[], read?: boolean): Promise { const promises = notifications.map((notification) => { // Set message to show. if (notification.contexturl && notification.contexturl.indexOf('/mod/forum/') >= 0) { @@ -55,6 +56,7 @@ export class AddonNotificationsProvider { } else { notification.mobiletext = notification.fullmessage; } + // Try to set courseid the notification belongs to. const cid = notification.fullmessagehtml.match(/course\/view\.php\?id=([^"]*)/); if (cid && cid[1]) { @@ -71,6 +73,11 @@ export class AddonNotificationsProvider { }); } + notification.notification = 1; + if (typeof read != 'undefined') { + notification.read = read; + } + return Promise.resolve(notification); }); @@ -154,7 +161,7 @@ export class AddonNotificationsProvider { if (response.messages) { const notifications = response.messages; - return this.formatNotificationsData(notifications).then(() => { + return this.formatNotificationsData(notifications, read).then(() => { if (this.appProvider.isDesktop() && toDisplay && !read && limitFrom === 0) { // Store the last received notification. Don't block the user for this. this.emulatorHelper.storeLastReceivedNotification( @@ -170,6 +177,67 @@ export class AddonNotificationsProvider { }); } + /** + * Get notifications from site using the new WebService. + * + * @param {number} offset Position of the first notification to get. + * @param {number} [limit] Number of notifications to get. Defaults to LIST_LIMIT. + * @param {boolean} [toDisplay=true] True if notifications will be displayed to the user, either in view or in a notification. + * @param {boolean} [forceCache] True if it should return cached data. Has priority over ignoreCache. + * @param {boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down). + * @param {string} [siteId] Site ID. If not defined, use current site. + * @return {Promise<{notifications: any[], canLoadMore: boolean}>} Promise resolved with notifications and if can load more. + * @since 3.2 + */ + getPopupNotifications(offset: number, limit?: number, toDisplay: boolean = true, forceCache?: boolean, ignoreCache?: boolean, + siteId?: string): Promise<{notifications: any[], canLoadMore: boolean}> { + + limit = limit || AddonNotificationsProvider.LIST_LIMIT; + + this.logger.debug('Get popup notifications from ' + offset + '. Limit: ' + limit); + + return this.sitesProvider.getSite(siteId).then((site) => { + const data = { + useridto: site.getUserId(), + newestfirst: 1, + offset: offset, + limit: limit + 1 // Get one more to calculate canLoadMore. + }, + preSets = { + cacheKey: this.getNotificationsCacheKey(), + omitExpires: forceCache, + getFromCache: forceCache || !ignoreCache, + emergencyCache: forceCache || !ignoreCache, + }; + + // Get notifications. + return site.read('message_popup_get_popup_notifications', data, preSets).then((response) => { + if (response.notifications) { + const result: any = { + canLoadMore: response.notifications.length > limit + }, + notifications = response.notifications.slice(0, limit); + + result.notifications = notifications; + + return this.formatNotificationsData(notifications).then(() => { + const first = notifications[0]; + + if (this.appProvider.isDesktop() && toDisplay && offset === 0 && first && !first.read) { + // Store the last received notification. Don't block the user for this. + this.emulatorHelper.storeLastReceivedNotification( + AddonNotificationsProvider.PUSH_SIMULATION_COMPONENT, first, siteId); + } + + return result; + }); + } else { + return Promise.reject(null); + } + }); + }); + } + /** * Get read notifications from site. * @@ -244,6 +312,18 @@ export class AddonNotificationsProvider { }); } + /** + * Returns whether or not popup WS is available for a certain site. + * + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with true if available, resolved with false or rejected otherwise. + */ + isPopupAvailable(siteId?: string): Promise { + return this.sitesProvider.getSite(siteId).then((site) => { + return site.wsAvailable('message_popup_get_popup_notifications'); + }); + } + /** * Mark all message notification as read. * From c9820170291dc6f3bf7c7639c5b95c75a3350e04 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 22 Mar 2019 13:08:03 +0100 Subject: [PATCH 2/4] MOBILE-2927 emulator: Adapt push simulation to new behaviour --- src/addon/notifications/providers/cron-handler.ts | 7 +++++-- src/core/emulator/providers/helper.ts | 12 +++++------- src/core/emulator/providers/local-notifications.ts | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/addon/notifications/providers/cron-handler.ts b/src/addon/notifications/providers/cron-handler.ts index 78f317c41..687b970e9 100644 --- a/src/addon/notifications/providers/cron-handler.ts +++ b/src/addon/notifications/providers/cron-handler.ts @@ -21,6 +21,7 @@ import { CoreSitesProvider } from '@providers/sites'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreEmulatorHelperProvider } from '@core/emulator/providers/helper'; import { AddonNotificationsProvider } from './notifications'; +import { AddonNotificationsHelperProvider } from './helper'; /** * Notifications cron handler. @@ -32,7 +33,7 @@ export class AddonNotificationsCronHandler implements CoreCronHandler { constructor(private appProvider: CoreAppProvider, private eventsProvider: CoreEventsProvider, private sitesProvider: CoreSitesProvider, private localNotifications: CoreLocalNotificationsProvider, private notificationsProvider: AddonNotificationsProvider, private textUtils: CoreTextUtilsProvider, - private emulatorHelper: CoreEmulatorHelperProvider) {} + private emulatorHelper: CoreEmulatorHelperProvider, private notificationsHelper: AddonNotificationsHelperProvider) {} /** * Get the time between consecutive executions. @@ -91,7 +92,9 @@ export class AddonNotificationsCronHandler implements CoreCronHandler { * @return {Promise} Promise resolved with the notifications. */ protected fetchNotifications(siteId: string): Promise { - return this.notificationsProvider.getUnreadNotifications(0, undefined, true, false, true, siteId); + return this.notificationsHelper.getNotifications([], undefined, true, false, true, siteId).then((result) => { + return result.notifications; + }); } /** diff --git a/src/core/emulator/providers/helper.ts b/src/core/emulator/providers/helper.ts index fc10a32a2..fc64ed0eb 100644 --- a/src/core/emulator/providers/helper.ts +++ b/src/core/emulator/providers/helper.ts @@ -161,17 +161,15 @@ export class CoreEmulatorHelperProvider implements CoreInitHandler { // There is a new notification, show it. return getDataFn(notification).then((titleAndText) => { + // Set some calculated data. + notification.site = siteId; + notification.name = notification.name || notification.eventtype; + const localNotif: ILocalNotification = { id: 1, - trigger: { - at: new Date() - }, title: titleAndText.title, text: titleAndText.text, - data: { - notif: notification, - site: siteId - } + data: notification }; return this.localNotifProvider.schedule(localNotif, component, siteId); diff --git a/src/core/emulator/providers/local-notifications.ts b/src/core/emulator/providers/local-notifications.ts index 3b943aba1..73d6ebfc4 100644 --- a/src/core/emulator/providers/local-notifications.ts +++ b/src/core/emulator/providers/local-notifications.ts @@ -630,7 +630,7 @@ export class LocalNotificationsMock extends LocalNotifications { * @return {number} Trigger time. */ protected getNotificationTriggerAt(notification: ILocalNotification): number { - const triggerAt = (notification.trigger && notification.trigger.at) || 0; + const triggerAt = (notification.trigger && notification.trigger.at) || new Date(); if (typeof triggerAt != 'number') { return triggerAt.getTime(); From 1146eea0fa30b4c62c7cea87ef40e5b27122b487 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Mon, 25 Mar 2019 14:40:05 +0100 Subject: [PATCH 3/4] MOBILE-2927 messages: Detect push in group conversations --- src/addon/messages/messages.module.ts | 4 +- .../messages/providers/mainmenu-handler.ts | 57 ++++++++++++++++++- src/addon/messages/providers/messages.ts | 34 +++++++++-- 3 files changed, 84 insertions(+), 11 deletions(-) diff --git a/src/addon/messages/messages.module.ts b/src/addon/messages/messages.module.ts index 2dd05562f..8cc6a9b7b 100644 --- a/src/addon/messages/messages.module.ts +++ b/src/addon/messages/messages.module.ts @@ -121,8 +121,8 @@ export class AddonMessagesModule { // Check if we have enough information to open the conversation. if (notification.convid && enabled) { pageParams.conversationId = Number(notification.convid); - } else if (notification.userfromid) { - pageParams.discussionUserId = Number(notification.userfromid); + } else if (notification.userfromid || notification.useridfrom) { + pageParams.discussionUserId = Number(notification.userfromid || notification.useridfrom); } linkHelper.goInSite(undefined, pageName, pageParams, notification.site); diff --git a/src/addon/messages/providers/mainmenu-handler.ts b/src/addon/messages/providers/mainmenu-handler.ts index 4b83ae499..155e0c2e8 100644 --- a/src/addon/messages/providers/mainmenu-handler.ts +++ b/src/addon/messages/providers/mainmenu-handler.ts @@ -229,8 +229,59 @@ export class AddonMessagesMainMenuHandler implements CoreMainMenuHandler, CoreCr * @return {Promise} Promise resolved with the notifications. */ protected fetchMessages(siteId?: string): Promise { - return this.messagesProvider.getUnreadReceivedMessages(true, false, true, siteId).then((response) => { - return response.messages; + return this.sitesProvider.getSite(siteId).then((site) => { + if (site.isVersionGreaterEqualThan('3.7')) { + + // Use get conversations WS to be able to get group conversations messages. + return this.messagesProvider.getConversations(undefined, undefined, 0, site.id, undefined, false, true) + .then((result) => { + + // Find the first unmuted conversation. + const conv = result.conversations.find((conversation) => { + return !conversation.ismuted; + }); + + if (conv.isread) { + // The conversation is read, no unread messages. + return []; + } + + const currentUserId = site.getUserId(), + message = conv.messages[0]; // Treat only the last message, is the one we're interested. + + if (!message || message.useridfrom == currentUserId) { + // No last message or not from current user. Return empty list. + return []; + } + + // Add some calculated data. + message.contexturl = ''; + message.contexturlname = ''; + message.convid = conv.id; + message.fullmessage = message.text; + message.fullmessageformat = 0; + message.fullmessagehtml = ''; + message.notification = 0; + message.read = 0; + message.smallmessage = message.smallmessage || message.text; + message.subject = conv.name; + message.timecreated = message.timecreated * 1000; + message.timeread = 0; + message.useridto = currentUserId; + message.usertofullname = site.getInfo().fullname; + + const userFrom = conv.members.find((member) => { + return member.id == message.useridfrom; + }); + message.userfromfullname = userFrom && userFrom.fullname; + + return [message]; + }); + } else { + return this.messagesProvider.getUnreadReceivedMessages(true, false, true, siteId).then((response) => { + return response.messages; + }); + } }); } @@ -242,7 +293,7 @@ export class AddonMessagesMainMenuHandler implements CoreMainMenuHandler, CoreCr */ protected getTitleAndText(message: any): Promise { const data = { - title: message.userfromfullname, + title: message.name || message.userfromfullname, }; return this.textUtils.formatText(message.text, true, true).catch(() => { diff --git a/src/addon/messages/providers/messages.ts b/src/addon/messages/providers/messages.ts index 6bf99d882..bfa615909 100644 --- a/src/addon/messages/providers/messages.ts +++ b/src/addon/messages/providers/messages.ts @@ -882,14 +882,20 @@ export class AddonMessagesProvider { result.messages = result.messages.slice(0, limitTo); } + let lastReceived; + result.messages.forEach((message) => { // Convert time to milliseconds. message.timecreated = message.timecreated ? message.timecreated * 1000 : 0; + + if (!lastReceived && message.useridfrom != userId) { + lastReceived = message; + } }); - if (this.appProvider.isDesktop() && params.useridto == userId && limitFrom === 0) { + if (this.appProvider.isDesktop() && limitFrom === 0 && lastReceived) { // Store the last received message (we cannot know if it's unread or not). Don't block the user for this. - this.storeLastReceivedMessageIfNeeded(conversationId, result.messages[0], site.getId()); + this.storeLastReceivedMessageIfNeeded(conversationId, lastReceived, site.getId()); } if (excludePending) { @@ -923,11 +929,13 @@ export class AddonMessagesProvider { * @param {number} [limitFrom=0] The offset to start at. * @param {string} [siteId] Site ID. If not defined, use current site. * @param {number} [userId] User ID. If not defined, current user in the site. + * @param {boolean} [forceCache] True if it should return cached data. Has priority over ignoreCache. + * @param {boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down). * @return {Promise} Promise resolved with the conversations. * @since 3.6 */ - getConversations(type?: number, favourites?: boolean, limitFrom: number = 0, siteId?: string, userId?: number) - : Promise<{conversations: any[], canLoadMore: boolean}> { + getConversations(type?: number, favourites?: boolean, limitFrom: number = 0, siteId?: string, userId?: number, + forceCache?: boolean, ignoreCache?: boolean): Promise<{conversations: any[], canLoadMore: boolean}> { return this.sitesProvider.getSite(siteId).then((site) => { userId = userId || site.getUserId(); @@ -941,6 +949,13 @@ export class AddonMessagesProvider { limitnum: this.LIMIT_MESSAGES + 1, }; + if (forceCache) { + preSets['omitExpires'] = true; + } else if (ignoreCache) { + preSets['getFromCache'] = false; + preSets['emergencyCache'] = false; + } + if (typeof type != 'undefined' && type != null) { params.type = type; } @@ -951,8 +966,15 @@ export class AddonMessagesProvider { return site.read('core_message_get_conversations', params, preSets).then((response) => { // Format the conversations, adding some calculated fields. const conversations = response.conversations.slice(0, this.LIMIT_MESSAGES).map((conversation) => { - return this.formatConversation(conversation, userId); - }); + return this.formatConversation(conversation, userId); + }), + conv = conversations[0], + lastMessage = conv && conv.messages[0]; + + if (this.appProvider.isDesktop() && limitFrom === 0 && lastMessage && !conv.sentfromcurrentuser) { + // Store the last received message (we cannot know if it's unread or not). Don't block the user for this. + this.storeLastReceivedMessageIfNeeded(conv.id, lastMessage, site.getId()); + } return { conversations: conversations, From b9aa0e0a9081ea0d7d13b5965868a0c71a93539f Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 26 Mar 2019 11:20:44 +0100 Subject: [PATCH 4/4] MOBILE-2927 notifications: Make push simulation use new delegate --- .../notifications/notifications.module.ts | 28 ++++++------------- .../notifications/providers/cron-handler.ts | 2 +- .../notifications/providers/notifications.ts | 2 ++ .../providers/push-click-handler.ts | 4 ++- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/addon/notifications/notifications.module.ts b/src/addon/notifications/notifications.module.ts index d5042b001..2a2b94021 100644 --- a/src/addon/notifications/notifications.module.ts +++ b/src/addon/notifications/notifications.module.ts @@ -20,13 +20,11 @@ import { AddonNotificationsSettingsHandler } from './providers/settings-handler' import { AddonNotificationsCronHandler } from './providers/cron-handler'; import { AddonNotificationsPushClickHandler } from './providers/push-click-handler'; import { CoreAppProvider } from '@providers/app'; -import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper'; +import { CoreInitDelegate } from '@providers/init'; import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate'; import { CoreSettingsDelegate } from '@core/settings/providers/delegate'; import { CoreCronDelegate } from '@providers/cron'; import { CoreLocalNotificationsProvider } from '@providers/local-notifications'; -import { CoreSitesProvider } from '@providers/sites'; -import { CoreUtilsProvider } from '@providers/utils/utils'; import { CorePushNotificationsDelegate } from '@core/pushnotifications/providers/delegate'; // List of providers (without handlers). @@ -53,9 +51,8 @@ export class AddonNotificationsModule { constructor(mainMenuDelegate: CoreMainMenuDelegate, mainMenuHandler: AddonNotificationsMainMenuHandler, settingsDelegate: CoreSettingsDelegate, settingsHandler: AddonNotificationsSettingsHandler, cronDelegate: CoreCronDelegate, cronHandler: AddonNotificationsCronHandler, zone: NgZone, - appProvider: CoreAppProvider, utils: CoreUtilsProvider, sitesProvider: CoreSitesProvider, - notificationsProvider: AddonNotificationsProvider, localNotifications: CoreLocalNotificationsProvider, - linkHelper: CoreContentLinksHelperProvider, pushNotificationsDelegate: CorePushNotificationsDelegate, + appProvider: CoreAppProvider, localNotifications: CoreLocalNotificationsProvider, + initDelegate: CoreInitDelegate, pushNotificationsDelegate: CorePushNotificationsDelegate, pushClickHandler: AddonNotificationsPushClickHandler) { mainMenuDelegate.registerHandler(mainMenuHandler); @@ -63,22 +60,13 @@ export class AddonNotificationsModule { cronDelegate.register(cronHandler); pushNotificationsDelegate.registerClickHandler(pushClickHandler); - const notificationClicked = (notification: any): void => { - sitesProvider.isFeatureDisabled('CoreMainMenuDelegate_AddonNotifications', notification.site).then((disabled) => { - if (disabled) { - // Notifications are disabled, stop. - return; - } - - notificationsProvider.invalidateNotificationsList().finally(() => { - linkHelper.goInSite(undefined, 'AddonNotificationsListPage', undefined, notification.site); - }); - }); - }; - if (appProvider.isDesktop()) { // Listen for clicks in simulated push notifications. - localNotifications.registerClick(AddonNotificationsProvider.PUSH_SIMULATION_COMPONENT, notificationClicked); + localNotifications.registerClick(AddonNotificationsProvider.PUSH_SIMULATION_COMPONENT, (notification) => { + initDelegate.ready().then(() => { + pushNotificationsDelegate.clicked(notification); + }); + }); } } } diff --git a/src/addon/notifications/providers/cron-handler.ts b/src/addon/notifications/providers/cron-handler.ts index 687b970e9..e16ed9a1f 100644 --- a/src/addon/notifications/providers/cron-handler.ts +++ b/src/addon/notifications/providers/cron-handler.ts @@ -105,7 +105,7 @@ export class AddonNotificationsCronHandler implements CoreCronHandler { */ protected getTitleAndText(notification: any): Promise { const data = { - title: notification.userfromfullname, + title: notification.subject || notification.userfromfullname, text: notification.mobiletext.replace(/-{4,}/ig, '') }; data.text = this.textUtils.replaceNewLines(data.text, '
'); diff --git a/src/addon/notifications/providers/notifications.ts b/src/addon/notifications/providers/notifications.ts index b52578a53..d268cff1a 100644 --- a/src/addon/notifications/providers/notifications.ts +++ b/src/addon/notifications/providers/notifications.ts @@ -73,7 +73,9 @@ export class AddonNotificationsProvider { }); } + notification.moodlecomponent = notification.component; notification.notification = 1; + notification.notif = 1; if (typeof read != 'undefined') { notification.read = read; } diff --git a/src/addon/notifications/providers/push-click-handler.ts b/src/addon/notifications/providers/push-click-handler.ts index 4d8d2f382..11450bb23 100644 --- a/src/addon/notifications/providers/push-click-handler.ts +++ b/src/addon/notifications/providers/push-click-handler.ts @@ -40,7 +40,9 @@ export class AddonNotificationsPushClickHandler implements CorePushNotifications handles(notification: any): boolean | Promise { if (this.utils.isTrueOrOne(notification.notif)) { // Notification clicked, mark as read. Don't block for this. - this.notificationsProvider.markNotificationRead(notification.savedmessageid, notification.site).then(() => { + const notifId = notification.savedmessageid || notification.id; + + this.notificationsProvider.markNotificationRead(notifId, notification.site).then(() => { this.eventsProvider.trigger(AddonNotificationsProvider.READ_CHANGED_EVENT, null, notification.site); }).catch(() => { // Ignore errors.