From 7c0155aeb56b3bdd9d725982fbf17c2e9a0563c5 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Tue, 7 Jan 2020 11:07:35 +0800 Subject: [PATCH] MDL-66237 message_popup: Get redirecturl from notification contexturl --- .../amd/build/notification_popover_controller.min.js | 2 +- .../amd/build/notification_popover_controller.min.js.map | 2 +- .../popup/amd/src/notification_popover_controller.js | 4 +--- message/output/popup/mark_notification_read.php | 8 +++++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/message/output/popup/amd/build/notification_popover_controller.min.js b/message/output/popup/amd/build/notification_popover_controller.min.js index 1317ee5d9e743..aca97e27db4f9 100644 --- a/message/output/popup/amd/build/notification_popover_controller.min.js +++ b/message/output/popup/amd/build/notification_popover_controller.min.js @@ -1,2 +1,2 @@ -define ("message_popup/notification_popover_controller",["jquery","core/ajax","core/templates","core/str","core/url","core/notification","core/custom_interaction_events","core/popover_region_controller","message_popup/notification_repository","message_popup/notification_area_events"],function(a,b,c,d,e,f,g,h,i,j){var k={MARK_ALL_READ_BUTTON:"[data-action=\"mark-all-read\"]",ALL_NOTIFICATIONS_CONTAINER:"[data-region=\"all-notifications\"]",NOTIFICATION:"[data-region=\"notification-content-item-container\"]",UNREAD_NOTIFICATION:"[data-region=\"notification-content-item-container\"].unread",NOTIFICATION_LINK:"[data-action=\"content-item-link\"]",EMPTY_MESSAGE:"[data-region=\"empty-message\"]",COUNT_CONTAINER:"[data-region=\"count-container\"]"},l=function(a){h.call(this,a);this.markAllReadButton=this.root.find(k.MARK_ALL_READ_BUTTON);this.unreadCount=0;this.userId=this.root.attr("data-userid");this.container=this.root.find(k.ALL_NOTIFICATIONS_CONTAINER);this.limit=20;this.offset=0;this.loadedAll=!1;this.initialLoad=!1;this.unreadCount=this.root.find(k.COUNT_CONTAINER).html()};l.prototype=Object.create(h.prototype);l.prototype.constructor=l;l.prototype.updateButtonAriaLabel=function(){if(this.isMenuOpen()){d.get_string("hidenotificationwindow","message").done(function(a){this.menuToggle.attr("aria-label",a)}.bind(this))}else{if(this.unreadCount){d.get_string("shownotificationwindowwithcount","message",this.unreadCount).done(function(a){this.menuToggle.attr("aria-label",a)}.bind(this))}else{d.get_string("shownotificationwindownonew","message").done(function(a){this.menuToggle.attr("aria-label",a)}.bind(this))}}};l.prototype.getContent=function(){return this.container};l.prototype.getOffset=function(){return this.offset};l.prototype.incrementOffset=function(){this.offset+=this.limit};l.prototype.hasDoneInitialLoad=function(){return this.initialLoad};l.prototype.hasLoadedAllContent=function(){return this.loadedAll};l.prototype.setLoadedAllContent=function(a){this.loadedAll=a};l.prototype.renderUnreadCount=function(){var a=this.root.find(k.COUNT_CONTAINER);if(this.unreadCount){a.text(this.unreadCount);a.removeClass("hidden")}else{a.addClass("hidden")}};l.prototype.hideUnreadCount=function(){this.root.find(k.COUNT_CONTAINER).addClass("hidden")};l.prototype.getNotificationElement=function(a){var b=this.root.find(k.NOTIFICATION+"[data-id=\""+a+"\"]");return 1==b.length?b:null};l.prototype.renderNotifications=function(b,d){var f=[];a.each(b,function(a,b){var d=this.getOffset()-this.limit;b.viewmoreurl=e.relativeUrl("/message/output/popup/notifications.php",{notificationid:b.id,offset:d});var g={notificationid:b.id};if(b.contexturl){g.redirecturl=encodeURIComponent(b.contexturl)}b.contexturl=e.relativeUrl("message/output/popup/mark_notification_read.php",g);var h=c.render("message_popup/notification_content_item",b).then(function(a,b){return{html:a,js:b}});f.push(h)}.bind(this));return a.when.apply(a,f).then(function(){a.each(arguments,function(a,b){d.append(b.html);c.runTemplateJS(b.js)})})};l.prototype.loadMoreNotifications=function(){if(this.isLoading||this.hasLoadedAllContent()){return a.Deferred().resolve()}this.startLoading();var b={limit:this.limit,offset:this.getOffset(),useridto:this.userId},c=this.getContent();return i.query(b).then(function(a){var b=a.notifications;this.unreadCount=a.unreadcount;this.setLoadedAllContent(!b.length||b.length.\n\n/**\n * Controls the notification popover in the nav bar.\n *\n * See template: message_popup/notification_popover\n *\n * @module message_popup/notification_popover_controller\n * @class notification_popover_controller\n * @package message_popup\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/ajax', 'core/templates', 'core/str', 'core/url',\n 'core/notification', 'core/custom_interaction_events', 'core/popover_region_controller',\n 'message_popup/notification_repository', 'message_popup/notification_area_events'],\n function($, Ajax, Templates, Str, URL, DebugNotification, CustomEvents,\n PopoverController, NotificationRepo, NotificationAreaEvents) {\n\n var SELECTORS = {\n MARK_ALL_READ_BUTTON: '[data-action=\"mark-all-read\"]',\n ALL_NOTIFICATIONS_CONTAINER: '[data-region=\"all-notifications\"]',\n NOTIFICATION: '[data-region=\"notification-content-item-container\"]',\n UNREAD_NOTIFICATION: '[data-region=\"notification-content-item-container\"].unread',\n NOTIFICATION_LINK: '[data-action=\"content-item-link\"]',\n EMPTY_MESSAGE: '[data-region=\"empty-message\"]',\n COUNT_CONTAINER: '[data-region=\"count-container\"]',\n };\n\n /**\n * Constructor for the NotificationPopoverController.\n * Extends PopoverRegionController.\n *\n * @param {object} element jQuery object root element of the popover\n */\n var NotificationPopoverController = function(element) {\n // Initialise base class.\n PopoverController.call(this, element);\n\n this.markAllReadButton = this.root.find(SELECTORS.MARK_ALL_READ_BUTTON);\n this.unreadCount = 0;\n this.userId = this.root.attr('data-userid');\n this.container = this.root.find(SELECTORS.ALL_NOTIFICATIONS_CONTAINER);\n this.limit = 20;\n this.offset = 0;\n this.loadedAll = false;\n this.initialLoad = false;\n\n // Let's find out how many unread notifications there are.\n this.unreadCount = this.root.find(SELECTORS.COUNT_CONTAINER).html();\n };\n\n /**\n * Clone the parent prototype.\n */\n NotificationPopoverController.prototype = Object.create(PopoverController.prototype);\n\n /**\n * Make sure the constructor is set correctly.\n */\n NotificationPopoverController.prototype.constructor = NotificationPopoverController;\n\n /**\n * Set the correct aria label on the menu toggle button to be read out by screen\n * readers. The message will indicate the state of the unread notifications.\n *\n * @method updateButtonAriaLabel\n */\n NotificationPopoverController.prototype.updateButtonAriaLabel = function() {\n if (this.isMenuOpen()) {\n Str.get_string('hidenotificationwindow', 'message').done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n } else {\n if (this.unreadCount) {\n Str.get_string('shownotificationwindowwithcount', 'message', this.unreadCount).done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n } else {\n Str.get_string('shownotificationwindownonew', 'message').done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n }\n }\n };\n\n /**\n * Return the jQuery element with the content. This will return either\n * the unread notification container or the all notification container\n * depending on which is currently visible.\n *\n * @method getContent\n * @return {object} jQuery object currently visible content contianer\n */\n NotificationPopoverController.prototype.getContent = function() {\n return this.container;\n };\n\n /**\n * Get the offset value for the current state of the popover in order\n * to sent to the backend to correctly paginate the notifications.\n *\n * @method getOffset\n * @return {int} current offset\n */\n NotificationPopoverController.prototype.getOffset = function() {\n return this.offset;\n };\n\n /**\n * Increment the offset for the current state, if required.\n *\n * @method incrementOffset\n */\n NotificationPopoverController.prototype.incrementOffset = function() {\n this.offset += this.limit;\n };\n\n /**\n * Check if the first load of notification has been triggered for the current\n * state of the popover.\n *\n * @method hasDoneInitialLoad\n * @return {bool} true if first notification loaded, false otherwise\n */\n NotificationPopoverController.prototype.hasDoneInitialLoad = function() {\n return this.initialLoad;\n };\n\n /**\n * Check if we've loaded all of the notifications for the current popover\n * state.\n *\n * @method hasLoadedAllContent\n * @return {bool} true if all notifications loaded, false otherwise\n */\n NotificationPopoverController.prototype.hasLoadedAllContent = function() {\n return this.loadedAll;\n };\n\n /**\n * Set the state of the loaded all content property for the current state\n * of the popover.\n *\n * @method setLoadedAllContent\n * @param {bool} val True if all content is loaded, false otherwise\n */\n NotificationPopoverController.prototype.setLoadedAllContent = function(val) {\n this.loadedAll = val;\n };\n\n /**\n * Show the unread notification count badge on the menu toggle if there\n * are unread notifications, otherwise hide it.\n *\n * @method renderUnreadCount\n */\n NotificationPopoverController.prototype.renderUnreadCount = function() {\n var element = this.root.find(SELECTORS.COUNT_CONTAINER);\n\n if (this.unreadCount) {\n element.text(this.unreadCount);\n element.removeClass('hidden');\n } else {\n element.addClass('hidden');\n }\n };\n\n /**\n * Hide the unread notification count badge on the menu toggle.\n *\n * @method hideUnreadCount\n */\n NotificationPopoverController.prototype.hideUnreadCount = function() {\n this.root.find(SELECTORS.COUNT_CONTAINER).addClass('hidden');\n };\n\n /**\n * Find the notification element for the given id.\n *\n * @param {int} id\n * @method getNotificationElement\n * @return {object|null} The notification element\n */\n NotificationPopoverController.prototype.getNotificationElement = function(id) {\n var element = this.root.find(SELECTORS.NOTIFICATION + '[data-id=\"' + id + '\"]');\n return element.length == 1 ? element : null;\n };\n\n /**\n * Render the notification data with the appropriate template and add it to the DOM.\n *\n * @method renderNotifications\n * @param {array} notifications Notification data\n * @param {object} container jQuery object the container to append the rendered notifications\n * @return {object} jQuery promise that is resolved when all notifications have been\n * rendered and added to the DOM\n */\n NotificationPopoverController.prototype.renderNotifications = function(notifications, container) {\n var promises = [];\n\n $.each(notifications, function(index, notification) {\n // Determine what the offset was when loading this notification.\n var offset = this.getOffset() - this.limit;\n // Update the view more url to contain the offset to allow the notifications\n // page to load to the correct position in the list of notifications.\n notification.viewmoreurl = URL.relativeUrl('/message/output/popup/notifications.php', {\n notificationid: notification.id,\n offset: offset,\n });\n\n // Link to mark read page before loading the actual link.\n var notificationurlparams = {\n notificationid: notification.id\n };\n if (notification.contexturl) {\n notificationurlparams.redirecturl = encodeURIComponent(notification.contexturl);\n }\n notification.contexturl = URL.relativeUrl('message/output/popup/mark_notification_read.php', notificationurlparams);\n\n var promise = Templates.render('message_popup/notification_content_item', notification)\n .then(function(html, js) {\n return {html: html, js: js};\n });\n promises.push(promise);\n }.bind(this));\n\n return $.when.apply($, promises).then(function() {\n // Each of the promises in the when will pass its results as an argument to the function.\n // The order of the arguments will be the order that the promises are passed to when()\n // i.e. the first promise's results will be in the first argument.\n $.each(arguments, function(index, argument) {\n container.append(argument.html);\n Templates.runTemplateJS(argument.js);\n });\n return;\n });\n };\n\n /**\n * Send a request for more notifications from the server, if we aren't already\n * loading some and haven't already loaded all of them.\n *\n * Takes into account the current mode of the popover and will request only\n * unread notifications if required.\n *\n * All notifications are marked as read by the server when they are returned.\n *\n * @method loadMoreNotifications\n * @return {object} jQuery promise that is resolved when notifications have been\n * retrieved and added to the DOM\n */\n NotificationPopoverController.prototype.loadMoreNotifications = function() {\n if (this.isLoading || this.hasLoadedAllContent()) {\n return $.Deferred().resolve();\n }\n\n this.startLoading();\n var request = {\n limit: this.limit,\n offset: this.getOffset(),\n useridto: this.userId,\n };\n\n var container = this.getContent();\n return NotificationRepo.query(request).then(function(result) {\n var notifications = result.notifications;\n this.unreadCount = result.unreadcount;\n this.setLoadedAllContent(!notifications.length || notifications.length < this.limit);\n this.initialLoad = true;\n this.updateButtonAriaLabel();\n\n if (notifications.length) {\n this.incrementOffset();\n return this.renderNotifications(notifications, container);\n }\n\n return false;\n }.bind(this))\n .always(function() {\n this.stopLoading();\n }.bind(this));\n };\n\n /**\n * Send a request to the server to mark all unread notifications as read and update\n * the unread count and unread notification elements appropriately.\n *\n * @return {Promise}\n * @method markAllAsRead\n */\n NotificationPopoverController.prototype.markAllAsRead = function() {\n this.markAllReadButton.addClass('loading');\n\n return NotificationRepo.markAllAsRead({useridto: this.userId})\n .then(function() {\n this.unreadCount = 0;\n this.root.find(SELECTORS.UNREAD_NOTIFICATION).removeClass('unread');\n }.bind(this))\n .always(function() {\n this.markAllReadButton.removeClass('loading');\n }.bind(this));\n };\n\n /**\n * Add all of the required event listeners for this notification popover.\n *\n * @method registerEventListeners\n */\n NotificationPopoverController.prototype.registerEventListeners = function() {\n CustomEvents.define(this.root, [\n CustomEvents.events.activate,\n ]);\n\n // Mark all notifications read if the user activates the mark all as read button.\n this.root.on(CustomEvents.events.activate, SELECTORS.MARK_ALL_READ_BUTTON, function(e, data) {\n this.markAllAsRead();\n e.stopPropagation();\n data.originalEvent.preventDefault();\n }.bind(this));\n\n // Mark individual notification read if the user activates it.\n this.root.on(CustomEvents.events.activate, SELECTORS.NOTIFICATION_LINK, function(e) {\n var element = $(e.target).closest(SELECTORS.NOTIFICATION);\n\n if (element.hasClass('unread')) {\n this.unreadCount--;\n element.removeClass('unread');\n }\n\n e.stopPropagation();\n }.bind(this));\n\n // Update the notification information when the menu is opened.\n this.root.on(this.events().menuOpened, function() {\n this.hideUnreadCount();\n this.updateButtonAriaLabel();\n\n if (!this.hasDoneInitialLoad()) {\n this.loadMoreNotifications();\n }\n }.bind(this));\n\n // Update the unread notification count when the menu is closed.\n this.root.on(this.events().menuClosed, function() {\n this.renderUnreadCount();\n this.updateButtonAriaLabel();\n }.bind(this));\n\n // Set aria attributes when popover is loading.\n this.root.on(this.events().startLoading, function() {\n this.getContent().attr('aria-busy', 'true');\n }.bind(this));\n\n // Set aria attributes when popover is finished loading.\n this.root.on(this.events().stopLoading, function() {\n this.getContent().attr('aria-busy', 'false');\n }.bind(this));\n\n // Load more notifications if the user has scrolled to the end of content\n // item list.\n this.getContentContainer().on(CustomEvents.events.scrollBottom, function() {\n if (!this.isLoading && !this.hasLoadedAllContent()) {\n this.loadMoreNotifications();\n }\n }.bind(this));\n\n // Stop mouse scroll from propagating to the window element and\n // scrolling the page.\n CustomEvents.define(this.getContentContainer(), [\n CustomEvents.events.scrollLock\n ]);\n\n // Listen for when a notification is shown in the notifications page and mark\n // it as read, if it's unread.\n $(document).on(NotificationAreaEvents.notificationShown, function(e, notification) {\n if (!notification.read) {\n var element = this.getNotificationElement(notification.id);\n\n if (element) {\n element.removeClass('unread');\n }\n\n this.unreadCount--;\n this.renderUnreadCount();\n }\n }.bind(this));\n };\n\n return NotificationPopoverController;\n});\n"],"file":"notification_popover_controller.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/notification_popover_controller.js"],"names":["define","$","Ajax","Templates","Str","URL","DebugNotification","CustomEvents","PopoverController","NotificationRepo","NotificationAreaEvents","SELECTORS","MARK_ALL_READ_BUTTON","ALL_NOTIFICATIONS_CONTAINER","NOTIFICATION","UNREAD_NOTIFICATION","NOTIFICATION_LINK","EMPTY_MESSAGE","COUNT_CONTAINER","NotificationPopoverController","element","call","markAllReadButton","root","find","unreadCount","userId","attr","container","limit","offset","loadedAll","initialLoad","html","prototype","Object","create","constructor","updateButtonAriaLabel","isMenuOpen","get_string","done","string","menuToggle","bind","getContent","getOffset","incrementOffset","hasDoneInitialLoad","hasLoadedAllContent","setLoadedAllContent","val","renderUnreadCount","text","removeClass","addClass","hideUnreadCount","getNotificationElement","id","length","renderNotifications","notifications","promises","each","index","notification","viewmoreurl","relativeUrl","notificationid","notificationurlparams","contexturl","promise","render","then","js","push","when","apply","arguments","argument","append","runTemplateJS","loadMoreNotifications","isLoading","Deferred","resolve","startLoading","request","useridto","query","result","unreadcount","always","stopLoading","markAllAsRead","registerEventListeners","events","activate","on","e","data","stopPropagation","originalEvent","preventDefault","target","closest","hasClass","menuOpened","menuClosed","getContentContainer","scrollBottom","scrollLock","document","notificationShown","read"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the notification popover in the nav bar.\n *\n * See template: message_popup/notification_popover\n *\n * @module message_popup/notification_popover_controller\n * @class notification_popover_controller\n * @package message_popup\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/ajax', 'core/templates', 'core/str', 'core/url',\n 'core/notification', 'core/custom_interaction_events', 'core/popover_region_controller',\n 'message_popup/notification_repository', 'message_popup/notification_area_events'],\n function($, Ajax, Templates, Str, URL, DebugNotification, CustomEvents,\n PopoverController, NotificationRepo, NotificationAreaEvents) {\n\n var SELECTORS = {\n MARK_ALL_READ_BUTTON: '[data-action=\"mark-all-read\"]',\n ALL_NOTIFICATIONS_CONTAINER: '[data-region=\"all-notifications\"]',\n NOTIFICATION: '[data-region=\"notification-content-item-container\"]',\n UNREAD_NOTIFICATION: '[data-region=\"notification-content-item-container\"].unread',\n NOTIFICATION_LINK: '[data-action=\"content-item-link\"]',\n EMPTY_MESSAGE: '[data-region=\"empty-message\"]',\n COUNT_CONTAINER: '[data-region=\"count-container\"]',\n };\n\n /**\n * Constructor for the NotificationPopoverController.\n * Extends PopoverRegionController.\n *\n * @param {object} element jQuery object root element of the popover\n */\n var NotificationPopoverController = function(element) {\n // Initialise base class.\n PopoverController.call(this, element);\n\n this.markAllReadButton = this.root.find(SELECTORS.MARK_ALL_READ_BUTTON);\n this.unreadCount = 0;\n this.userId = this.root.attr('data-userid');\n this.container = this.root.find(SELECTORS.ALL_NOTIFICATIONS_CONTAINER);\n this.limit = 20;\n this.offset = 0;\n this.loadedAll = false;\n this.initialLoad = false;\n\n // Let's find out how many unread notifications there are.\n this.unreadCount = this.root.find(SELECTORS.COUNT_CONTAINER).html();\n };\n\n /**\n * Clone the parent prototype.\n */\n NotificationPopoverController.prototype = Object.create(PopoverController.prototype);\n\n /**\n * Make sure the constructor is set correctly.\n */\n NotificationPopoverController.prototype.constructor = NotificationPopoverController;\n\n /**\n * Set the correct aria label on the menu toggle button to be read out by screen\n * readers. The message will indicate the state of the unread notifications.\n *\n * @method updateButtonAriaLabel\n */\n NotificationPopoverController.prototype.updateButtonAriaLabel = function() {\n if (this.isMenuOpen()) {\n Str.get_string('hidenotificationwindow', 'message').done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n } else {\n if (this.unreadCount) {\n Str.get_string('shownotificationwindowwithcount', 'message', this.unreadCount).done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n } else {\n Str.get_string('shownotificationwindownonew', 'message').done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n }\n }\n };\n\n /**\n * Return the jQuery element with the content. This will return either\n * the unread notification container or the all notification container\n * depending on which is currently visible.\n *\n * @method getContent\n * @return {object} jQuery object currently visible content contianer\n */\n NotificationPopoverController.prototype.getContent = function() {\n return this.container;\n };\n\n /**\n * Get the offset value for the current state of the popover in order\n * to sent to the backend to correctly paginate the notifications.\n *\n * @method getOffset\n * @return {int} current offset\n */\n NotificationPopoverController.prototype.getOffset = function() {\n return this.offset;\n };\n\n /**\n * Increment the offset for the current state, if required.\n *\n * @method incrementOffset\n */\n NotificationPopoverController.prototype.incrementOffset = function() {\n this.offset += this.limit;\n };\n\n /**\n * Check if the first load of notification has been triggered for the current\n * state of the popover.\n *\n * @method hasDoneInitialLoad\n * @return {bool} true if first notification loaded, false otherwise\n */\n NotificationPopoverController.prototype.hasDoneInitialLoad = function() {\n return this.initialLoad;\n };\n\n /**\n * Check if we've loaded all of the notifications for the current popover\n * state.\n *\n * @method hasLoadedAllContent\n * @return {bool} true if all notifications loaded, false otherwise\n */\n NotificationPopoverController.prototype.hasLoadedAllContent = function() {\n return this.loadedAll;\n };\n\n /**\n * Set the state of the loaded all content property for the current state\n * of the popover.\n *\n * @method setLoadedAllContent\n * @param {bool} val True if all content is loaded, false otherwise\n */\n NotificationPopoverController.prototype.setLoadedAllContent = function(val) {\n this.loadedAll = val;\n };\n\n /**\n * Show the unread notification count badge on the menu toggle if there\n * are unread notifications, otherwise hide it.\n *\n * @method renderUnreadCount\n */\n NotificationPopoverController.prototype.renderUnreadCount = function() {\n var element = this.root.find(SELECTORS.COUNT_CONTAINER);\n\n if (this.unreadCount) {\n element.text(this.unreadCount);\n element.removeClass('hidden');\n } else {\n element.addClass('hidden');\n }\n };\n\n /**\n * Hide the unread notification count badge on the menu toggle.\n *\n * @method hideUnreadCount\n */\n NotificationPopoverController.prototype.hideUnreadCount = function() {\n this.root.find(SELECTORS.COUNT_CONTAINER).addClass('hidden');\n };\n\n /**\n * Find the notification element for the given id.\n *\n * @param {int} id\n * @method getNotificationElement\n * @return {object|null} The notification element\n */\n NotificationPopoverController.prototype.getNotificationElement = function(id) {\n var element = this.root.find(SELECTORS.NOTIFICATION + '[data-id=\"' + id + '\"]');\n return element.length == 1 ? element : null;\n };\n\n /**\n * Render the notification data with the appropriate template and add it to the DOM.\n *\n * @method renderNotifications\n * @param {array} notifications Notification data\n * @param {object} container jQuery object the container to append the rendered notifications\n * @return {object} jQuery promise that is resolved when all notifications have been\n * rendered and added to the DOM\n */\n NotificationPopoverController.prototype.renderNotifications = function(notifications, container) {\n var promises = [];\n\n $.each(notifications, function(index, notification) {\n // Determine what the offset was when loading this notification.\n var offset = this.getOffset() - this.limit;\n // Update the view more url to contain the offset to allow the notifications\n // page to load to the correct position in the list of notifications.\n notification.viewmoreurl = URL.relativeUrl('/message/output/popup/notifications.php', {\n notificationid: notification.id,\n offset: offset,\n });\n\n // Link to mark read page before loading the actual link.\n var notificationurlparams = {\n notificationid: notification.id\n };\n\n notification.contexturl = URL.relativeUrl('message/output/popup/mark_notification_read.php', notificationurlparams);\n\n var promise = Templates.render('message_popup/notification_content_item', notification)\n .then(function(html, js) {\n return {html: html, js: js};\n });\n promises.push(promise);\n }.bind(this));\n\n return $.when.apply($, promises).then(function() {\n // Each of the promises in the when will pass its results as an argument to the function.\n // The order of the arguments will be the order that the promises are passed to when()\n // i.e. the first promise's results will be in the first argument.\n $.each(arguments, function(index, argument) {\n container.append(argument.html);\n Templates.runTemplateJS(argument.js);\n });\n return;\n });\n };\n\n /**\n * Send a request for more notifications from the server, if we aren't already\n * loading some and haven't already loaded all of them.\n *\n * Takes into account the current mode of the popover and will request only\n * unread notifications if required.\n *\n * All notifications are marked as read by the server when they are returned.\n *\n * @method loadMoreNotifications\n * @return {object} jQuery promise that is resolved when notifications have been\n * retrieved and added to the DOM\n */\n NotificationPopoverController.prototype.loadMoreNotifications = function() {\n if (this.isLoading || this.hasLoadedAllContent()) {\n return $.Deferred().resolve();\n }\n\n this.startLoading();\n var request = {\n limit: this.limit,\n offset: this.getOffset(),\n useridto: this.userId,\n };\n\n var container = this.getContent();\n return NotificationRepo.query(request).then(function(result) {\n var notifications = result.notifications;\n this.unreadCount = result.unreadcount;\n this.setLoadedAllContent(!notifications.length || notifications.length < this.limit);\n this.initialLoad = true;\n this.updateButtonAriaLabel();\n\n if (notifications.length) {\n this.incrementOffset();\n return this.renderNotifications(notifications, container);\n }\n\n return false;\n }.bind(this))\n .always(function() {\n this.stopLoading();\n }.bind(this));\n };\n\n /**\n * Send a request to the server to mark all unread notifications as read and update\n * the unread count and unread notification elements appropriately.\n *\n * @return {Promise}\n * @method markAllAsRead\n */\n NotificationPopoverController.prototype.markAllAsRead = function() {\n this.markAllReadButton.addClass('loading');\n\n return NotificationRepo.markAllAsRead({useridto: this.userId})\n .then(function() {\n this.unreadCount = 0;\n this.root.find(SELECTORS.UNREAD_NOTIFICATION).removeClass('unread');\n }.bind(this))\n .always(function() {\n this.markAllReadButton.removeClass('loading');\n }.bind(this));\n };\n\n /**\n * Add all of the required event listeners for this notification popover.\n *\n * @method registerEventListeners\n */\n NotificationPopoverController.prototype.registerEventListeners = function() {\n CustomEvents.define(this.root, [\n CustomEvents.events.activate,\n ]);\n\n // Mark all notifications read if the user activates the mark all as read button.\n this.root.on(CustomEvents.events.activate, SELECTORS.MARK_ALL_READ_BUTTON, function(e, data) {\n this.markAllAsRead();\n e.stopPropagation();\n data.originalEvent.preventDefault();\n }.bind(this));\n\n // Mark individual notification read if the user activates it.\n this.root.on(CustomEvents.events.activate, SELECTORS.NOTIFICATION_LINK, function(e) {\n var element = $(e.target).closest(SELECTORS.NOTIFICATION);\n\n if (element.hasClass('unread')) {\n this.unreadCount--;\n element.removeClass('unread');\n }\n\n e.stopPropagation();\n }.bind(this));\n\n // Update the notification information when the menu is opened.\n this.root.on(this.events().menuOpened, function() {\n this.hideUnreadCount();\n this.updateButtonAriaLabel();\n\n if (!this.hasDoneInitialLoad()) {\n this.loadMoreNotifications();\n }\n }.bind(this));\n\n // Update the unread notification count when the menu is closed.\n this.root.on(this.events().menuClosed, function() {\n this.renderUnreadCount();\n this.updateButtonAriaLabel();\n }.bind(this));\n\n // Set aria attributes when popover is loading.\n this.root.on(this.events().startLoading, function() {\n this.getContent().attr('aria-busy', 'true');\n }.bind(this));\n\n // Set aria attributes when popover is finished loading.\n this.root.on(this.events().stopLoading, function() {\n this.getContent().attr('aria-busy', 'false');\n }.bind(this));\n\n // Load more notifications if the user has scrolled to the end of content\n // item list.\n this.getContentContainer().on(CustomEvents.events.scrollBottom, function() {\n if (!this.isLoading && !this.hasLoadedAllContent()) {\n this.loadMoreNotifications();\n }\n }.bind(this));\n\n // Stop mouse scroll from propagating to the window element and\n // scrolling the page.\n CustomEvents.define(this.getContentContainer(), [\n CustomEvents.events.scrollLock\n ]);\n\n // Listen for when a notification is shown in the notifications page and mark\n // it as read, if it's unread.\n $(document).on(NotificationAreaEvents.notificationShown, function(e, notification) {\n if (!notification.read) {\n var element = this.getNotificationElement(notification.id);\n\n if (element) {\n element.removeClass('unread');\n }\n\n this.unreadCount--;\n this.renderUnreadCount();\n }\n }.bind(this));\n };\n\n return NotificationPopoverController;\n});\n"],"file":"notification_popover_controller.min.js"} \ No newline at end of file diff --git a/message/output/popup/amd/src/notification_popover_controller.js b/message/output/popup/amd/src/notification_popover_controller.js index 8a6b04ff93435..c1e44e6eea42f 100644 --- a/message/output/popup/amd/src/notification_popover_controller.js +++ b/message/output/popup/amd/src/notification_popover_controller.js @@ -226,9 +226,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str', 'core/url', var notificationurlparams = { notificationid: notification.id }; - if (notification.contexturl) { - notificationurlparams.redirecturl = encodeURIComponent(notification.contexturl); - } + notification.contexturl = URL.relativeUrl('message/output/popup/mark_notification_read.php', notificationurlparams); var promise = Templates.render('message_popup/notification_content_item', notification) diff --git a/message/output/popup/mark_notification_read.php b/message/output/popup/mark_notification_read.php index 04586781b2629..9a8515ae061e8 100644 --- a/message/output/popup/mark_notification_read.php +++ b/message/output/popup/mark_notification_read.php @@ -31,11 +31,13 @@ } $notificationid = required_param('notificationid', PARAM_INT); -$redirecturl = optional_param('redirecturl', '', PARAM_URL); + $notification = $DB->get_record('notifications', array('id' => $notificationid)); // If the redirect URL after filtering is empty, or it was never passed, then redirect to the notification page. -if (empty($redirecturl)) { +if (!empty($notification->contexturl)) { + $redirecturl = new moodle_url($notification->contexturl); +} else { $redirecturl = new moodle_url('/message/output/popup/notifications.php', ['notificationid' => $notificationid]); } @@ -45,4 +47,4 @@ } \core_message\api::mark_notification_as_read($notification); -redirect(new moodle_url($redirecturl)); +redirect($redirecturl);