MDL-63303 message: fix bugs in message drawer part 4
[moodle.git] / message / amd / src / message_area_profile.js
blobeb73dcb5326895a892e3f917c03486790a4f3570
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /**
17  * This module handles the profile area of the messaging area.
18  *
19  * @module     core_message/message_area_profile
20  * @package    core_message
21  * @copyright  2016 Mark Nelson <markn@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
24 define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str', 'core/config',
25         'core/custom_interaction_events', 'core_message/message_area_events'],
26     function($, Ajax, Templates, Notification, Str, Config, CustomEvents, Events) {
28         /** @type {Object} The list of selectors for the message area. */
29         var SELECTORS = {
30             PROFILE: "[data-region='profile']",
31             PROFILEADDCONTACT: "[data-action='profile-add-contact']",
32             PROFILEBLOCKCONTACT: "[data-action='profile-block-contact']",
33             PROFILEREMOVECONTACT: "[data-action='profile-remove-contact']",
34             PROFILESENDMESSAGE: "[data-action='profile-send-message']",
35             PROFILEUNBLOCKCONTACT: "[data-action='profile-unblock-contact']",
36             PROFILEVIEW: "[data-action='profile-view']",
37             SHOWCONTACTS: "[data-action='show-contacts']",
38             MESSAGESAREA: "[data-region='messages-area']",
39             MESSAGINGAREA: "[data-region='messaging-area']"
40         };
42         /**
43          * Profile class.
44          *
45          * @param {Messagearea} messageArea The messaging area object.
46          */
47         function Profile(messageArea) {
48             this.messageArea = messageArea;
49             this._init();
50         }
52         /** @type {Messagearea} The messaging area object. */
53         Profile.prototype.messageArea = null;
55         /**
56          * Initialise the event listeners.
57          *
58          * @private
59          */
60         Profile.prototype._init = function() {
61             CustomEvents.define(this.messageArea.node, [
62                 CustomEvents.events.activate
63             ]);
65             this.messageArea.onCustomEvent(Events.CONTACTSELECTED, this._viewProfile.bind(this));
66             this.messageArea.onDelegateEvent(CustomEvents.events.activate, SELECTORS.PROFILEVIEW,
67                 function(e, data) {
68                     this._viewFullProfile();
69                     data.originalEvent.preventDefault();
70                 }.bind(this));
71             this.messageArea.onDelegateEvent(CustomEvents.events.activate, SELECTORS.PROFILESENDMESSAGE,
72                 function(e, data) {
73                     this._sendMessage();
74                     data.originalEvent.preventDefault();
75                 }.bind(this));
76             this.messageArea.onDelegateEvent(CustomEvents.events.activate, SELECTORS.PROFILEUNBLOCKCONTACT,
77                 function(e, data) {
78                     this._unblockContact();
79                     data.originalEvent.preventDefault();
80                 }.bind(this));
81             this.messageArea.onDelegateEvent(CustomEvents.events.activate, SELECTORS.PROFILEBLOCKCONTACT,
82                 function(e, data) {
83                     this._blockContact();
84                     data.originalEvent.preventDefault();
85                 }.bind(this));
86             this.messageArea.onDelegateEvent(CustomEvents.events.activate, SELECTORS.PROFILEADDCONTACT,
87                 function(e, data) {
88                     this._addContact();
89                     data.originalEvent.preventDefault();
90                 }.bind(this));
91             this.messageArea.onDelegateEvent(CustomEvents.events.activate, SELECTORS.PROFILEREMOVECONTACT,
92                 function(e, data) {
93                     this._removeContact();
94                     data.originalEvent.preventDefault();
95                 }.bind(this));
96             this.messageArea.onDelegateEvent(CustomEvents.events.activate, SELECTORS.SHOWCONTACTS,
97                 this._hideMessagingArea.bind(this));
98         };
100         /**
101          * Handles viewing the profile.
102          *
103          * @param {Event} event
104          * @param {int} userid
105          * @return {Promise} The promise resolved when the profile has been rendered
106          * @private
107          */
108         Profile.prototype._viewProfile = function(event, userid) {
109             // Show loading template.
110             Templates.render('core/loading', {}).done(function(html, js) {
111                 Templates.replaceNodeContents(this.messageArea.find(SELECTORS.MESSAGESAREA), html, js);
112             }.bind(this));
114             // Call the web service to return the profile.
115             var promises = Ajax.call([{
116                 methodname: 'core_message_data_for_messagearea_get_profile',
117                 args: {
118                     currentuserid: this.messageArea.getCurrentUserId(),
119                     otheruserid: userid
120                 }
121             }]);
123             // Show the profile.
124             return promises[0].then(function(data) {
125                 return Templates.render('core_message/message_area_profile', data);
126             }).then(function(html, js) {
127                 Templates.replaceNodeContents(this.messageArea.find(SELECTORS.MESSAGESAREA), html, js);
128             }.bind(this)).fail(Notification.exception);
129         };
131         /**
132          * Handles viewing the user's full profile.
133          *
134          * @private
135          */
136         Profile.prototype._viewFullProfile = function() {
137             window.location.href = Config.wwwroot + '/user/profile.php?id=' + this._getUserId();
138         };
140         /**
141          * Handles viewing the messages with the user.
142          *
143          * @private
144          */
145         Profile.prototype._sendMessage = function() {
146             this.messageArea.trigger(Events.SENDMESSAGE, this._getUserId());
147         };
149         /**
150          * Handles blocking the contact.
151          *
152          * @return {Promise} The promise resolved when the contact has been blocked
153          * @private
154          */
155         Profile.prototype._blockContact = function() {
156             var action = this._performAction('core_message_block_user', 'unblockcontact', 'profile-block-contact',
157                 'profile-unblock-contact', '');
158             return action.then(function() {
159                 this.messageArea.trigger(Events.CONTACTBLOCKED, this._getUserId());
160             }.bind(this));
161         };
163         /**
164          * Handles unblocking the contact.
165          *
166          * @return {Promise} The promise resolved when the contact has been unblocked
167          * @private
168          */
169         Profile.prototype._unblockContact = function() {
170             var action = this._performAction('core_message_unblock_user', 'blockcontact', 'profile-unblock-contact',
171                 'profile-block-contact', 'danger');
172             return action.then(function() {
173                 this.messageArea.trigger(Events.CONTACTUNBLOCKED, this._getUserId());
174             }.bind(this));
175         };
177         /**
178          * Handles adding the contact.
179          *
180          * @return {Promise} The promise resolved when the contact has been added
181          * @private
182          */
183         Profile.prototype._addContact = function() {
184             var action = this._performAction('core_message_create_contact_request', 'removecontact', 'profile-add-contact',
185                 'profile-remove-contact', 'danger');
186             return action.then(function() {
187                 this.messageArea.trigger(Events.CONTACTADDED, this._getUserId());
188             }.bind(this));
189         };
191         /**
192          * Handles removing the contact.
193          *
194          * @return {Promise} The promise resolved when the contact has been removed
195          * @private
196          */
197         Profile.prototype._removeContact = function() {
198             var action = this._performAction('core_message_delete_contacts', 'addcontact', 'profile-remove-contact',
199                 'profile-add-contact', '');
200             return action.then(function() {
201                 this.messageArea.trigger(Events.CONTACTREMOVED, this._getUserId());
202             }.bind(this));
203         };
205         /**
206          * Helper function to perform actions on the profile page.
207          *
208          * @param {String} service The web service to call.
209          * @param {String} string The string to change the button value to
210          * @param {String} oldaction The data-action of the button
211          * @param {string} newaction The data-action to change the button to
212          * @param {String} newclass The CSS class we want to add
213          * @return {Promise} The promise resolved when the action has been performed
214          * @private
215          */
216         Profile.prototype._performAction = function(service, string, oldaction, newaction, newclass) {
217             // This is a temporary hack as we are getting rid of this UI.
218             var userargs = '';
219             switch (service) {
220                 case 'core_message_block_user':
221                     userargs = {
222                         userid: this.messageArea.getCurrentUserId(),
223                         blockeduserid: this._getUserId()
224                     };
225                     break;
226                 case 'core_message_unblock_user':
227                     userargs = {
228                         userid: this.messageArea.getCurrentUserId(),
229                         unblockeduserid: this._getUserId()
230                     };
231                     break;
232                 case 'core_message_create_contact_request':
233                     userargs = {
234                         userid: this.messageArea.getCurrentUserId(),
235                         requesteduserid: this._getUserId()
236                     };
237                     break;
238                 default:
239                     userargs = {
240                         userid: this.messageArea.getCurrentUserId(),
241                         userids: [
242                             this._getUserId()
243                         ]
244                     };
245             }
248             var promises = Ajax.call([{
249                 methodname: service,
250                 args: userargs
251             }]);
253             return promises[0].then(function() {
254                 return Str.get_string(string, 'message');
255             }).then(function(s) {
256                 this._changeText(s, oldaction, newaction, newclass);
257             }.bind(this)).fail(Notification.exception);
258         };
260         /**
261          * Changes the text in the profile area.
262          *
263          * @param {String} text The string to change the button value to
264          * @param {string} oldaction The data-action of the button
265          * @param {string} newaction The data-action to change the button to
266          * @param {String} newclass The CSS class we want to add
267          * @private
268          */
269         Profile.prototype._changeText = function(text, oldaction, newaction, newclass) {
270             var anchor = this.messageArea.find("[data-action='" + oldaction + "']");
271             // Change the text.
272             anchor.text(text);
273             // Remove any class.
274             anchor.removeClass();
275             // Add the class if there is one.
276             if (newclass) {
277                 anchor.addClass(newclass);
278             }
280             anchor.attr('data-action', newaction);
281         };
283         /**
284          * Returns the ID of the user whos profile we are viewing.
285          *
286          * @return {int} The user ID
287          * @private
288          */
289         Profile.prototype._getUserId = function() {
290             return this.messageArea.find(SELECTORS.PROFILE).data('userid');
291         };
293         /**
294          * Hide the messaging area. This only applies on smaller screen resolutions.
295          */
296         Profile.prototype._hideMessagingArea = function() {
297             this.messageArea.find(SELECTORS.MESSAGINGAREA)
298                 .removeClass('show-messages')
299                 .addClass('hide-messages');
300         };
302         return Profile;
303     }