summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/js/models/threads/channel.js
diff options
context:
space:
mode:
authorAlexandre Kühn <aku@odoo.com>2018-08-11 20:30:51 +0200
committerAlexandre Kühn <aku@odoo.com>2018-08-13 14:17:27 +0200
commitf2302dfb27dd7f6a0dee7c65ab75b62a01706264 (patch)
treed58fef9e2e8a5b98c0680f28fc92e24992236029 /addons/mail/static/src/js/models/threads/channel.js
parent3de97f168956a7c22c3af6b72950cf28554f4139 (diff)
[REF][FIX] mail, im_livechat: various improvements (JS)
This commit makes a lot of small improvements of the JS of mail and related modules. A. Mail Manager --------------- im_support: - [REF] Slightly more robust way to determine a support message, so that it more reliably falls back on default kind of message (i.e. support channel UUID should be clearly set). mail: - [REF] Improved method names for readability purposes. Some examples: - `fetchFromServer` becomes `fetchMailStateFromServer` - `_initialize{*}` becomes `_update{*}FromServer` - `_isModerator` becomes `_isMyselfModerator` - [REF] Use 'template' pattern design to make Include on Mail Manager much more robust. In particular, the flow is always as follow: 1. Initialize internal state. 2. Listen on buses. 3. Fetch mail data from server. - [REF] Improved workflow for thread window workflow (Shorter & more readable). B. Mail Tests ------------- - [REF] Thread Window Tests crashes with clean message when there are some thread windows open before running the tests. C. (Model) Message ------------------ - [REF] Improved method names for readability purposes (e.g. `isAuthor` becomes `isMyselfAuthor`). D. (Model) Thread ----------------- - [REF] Improved `init` parameters on each kind of thread. - [REF] 'Thread With Cache' has been renamed to 'Searchable Thread': it embraces all kinds of threads that can be used with the search view. - [REF] 'DM' has been renamed to 'DM Chat' (for clarity). - [IMP] New Livechat model in the backend. - [REF] No more direct instances of the Channel class: public and private channels are now 'Multi-User' channels, while DM Chat and Livechat are 'Two-User' channels: This change has been made so that instances of classes always have direct classes as "leaf" in the Class modeling. It eases making changes to a certain model without being too constrained by another model. - [REF] As a consequence of above changed, the method `isChat` has been renamed to `isTwoUserThread`. This is to avoid confusion with the terminology 'chat', which is more like a shortcut for 'quick real- time conversation'. In other words, the property of 'chat' depends of the way to interact on a thread, not of the intrinsic type of the thread. Still, some parts have kept the terminology 'chat', such as in the systray messagin menu. - [IMP] Added `message_added` and `message_posted` hooks, which may be useful to easily hook on those events. E. Thread Widget ---------------- - [REF] Now uses a `mail.model.AbstractThread` for the rendering of a thread, instead of a list of `{mail.model.AbstractMessage}`. - [FIX] Stick thread scroll height to bottom on new rendering, if it was previously at the bottom of the thread. - [REF] Option ORDER has its meaning changed: it now refers to the chronological order of messages in the thread, in which DESC means 'from top to bottom', while ASC means 'from bottom to top'. - [REF] Improved doc on templates, in particular with the option `ORDER`. F. Thread Window ---------------- - [REF] Moved more logic to thread windows, which were previously in Mail Window Manager. - [REF] Now hides the thread widget attribute. So instead of `threadWindow.threadWidget.isAtBottom()`, it uses `threadWindow.isAtBottom()`. - [FIX] New received messages when not having focus on Odoo tab should always make the corresponding thread windows "passive" (i.e. windows that keep threads unread until click on them). - [FIX] Blank thread window (i.e. 'New message' TW) correctly opens Discuss with 'Inbox' when clicking on 'Expand' Button in the title - [FIX] Do not display the composer for channels with property 'mass-mailing' set in thread windows. G. (Website) Livechat --------------------- - [REF] Some `trigger` have been turned into `trigger_up`. - [REF] Some logic has been moved to models (e.g. `{im_livechat.model.WebsiteLivechat}`), from `{im_livechat.im_livechat.LivechatButton}`. - [FIX] New messages should be received in real-time. The longpolling was broken with a recent refactoring on bus service (6448420c5dd160470e465dee7729d19d8d5e7bab).
Diffstat (limited to 'addons/mail/static/src/js/models/threads/channel.js')
-rw-r--r--addons/mail/static/src/js/models/threads/channel.js162
1 files changed, 62 insertions, 100 deletions
diff --git a/addons/mail/static/src/js/models/threads/channel.js b/addons/mail/static/src/js/models/threads/channel.js
index a33319c7f1f..3f932ccb8ec 100644
--- a/addons/mail/static/src/js/models/threads/channel.js
+++ b/addons/mail/static/src/js/models/threads/channel.js
@@ -1,7 +1,7 @@
odoo.define('mail.model.Channel', function (require) {
"use strict";
-var ThreadWithCache = require('mail.model.ThreadWithCache');
+var SearchableThread = require('mail.model.SearchableThread');
var mailUtils = require('mail.utils');
var session = require('web.session');
@@ -15,12 +15,11 @@ var time = require('web.time');
* Any piece of code in JS that make use of channels must ideally interact with
* such objects, instead of direct data from the server.
*/
-var Channel = ThreadWithCache.extend({
+var Channel = SearchableThread.extend({
/**
* @override
* @param {Object} params
* @param {Object} params.data
- * @param {string} [params.data.anonymous_name]
* @param {string} params.data.channel_type
* @param {integer} [params.data.create_uid] the ID of the user that has
* created the channel.
@@ -29,9 +28,7 @@ var Channel = ThreadWithCache.extend({
* @param {boolean} params.data.is_moderator whether the current user is
* moderator of this channel.
* @param {string} [params.data.last_message_date] date in server-format
- * @param {boolean} [params.data.mass_mailing]
* @param {integer} [params.data.message_unread_counter]
- * @param {string} [params.data.public] either 'public' or 'private'
* @param {string} params.data.state
* @param {string} [params.data.uuid]
* @param {Object} params.options
@@ -48,9 +45,8 @@ var Channel = ThreadWithCache.extend({
// If set, autoswitch channel on joining this channel in discuss
// the default behaviour is to autoswitch on join.
- // exception: receiving channel or chat session notifications
+ // exception: receiving channel session notifications
this._autoswitch = 'autoswitch' in options ? options.autoswitch : true;
- this._chat = undefined; // FIXME: could be dropped when livechat and DM are moved out of this class
this._commands = undefined;
this._creatorUID = data.create_uid;
this._detached = data.is_minimized;
@@ -58,12 +54,12 @@ var Channel = ThreadWithCache.extend({
this._folded = data.state === 'folded';
// if set: hide 'Leave channel' button
this._groupBasedSubscription = data.group_based_subscription;
- this._isModerator = data.is_moderator;
+ this._isModerated = data.is_moderation;
+ this._isMyselfModerator = data.is_moderator;
this._lastMessageDate = undefined;
- this._massMailing = data.mass_mailing;
+ this._members = [];
// Deferred that is resolved on fetched members of this channel.
this._membersDef = undefined;
- this._moderation = data.is_moderation;
// number of messages that are 'needaction', which is equivalent to the
// number of messages in this channel that are in inbox.
this._needactionCounter = data.message_needaction_counter || 0;
@@ -78,16 +74,9 @@ var Channel = ThreadWithCache.extend({
return !command.channel_types ||
_.contains(command.channel_types, self._serverType);
});
- if (this._type === 'channel') {
- this._type = data.public !== 'private' ? 'public' : 'private';
- }
- if ('anonymous_name' in data) {
- this._name = data.anonymous_name;
- }
if (data.last_message_date) {
this._lastMessageDate = moment(time.str_to_datetime(data.last_message_date));
}
- this._chat = !this.getType().match(/^(public|private)$/);
if (data.message_unread_counter) {
this._unreadCounter = data.message_unread_counter;
}
@@ -190,6 +179,7 @@ var Channel = ThreadWithCache.extend({
* @returns {$.Promise<Object[]>} resolved with list of channel listeners
*/
getMentionPartnerSuggestions: function () {
+ var self = this;
if (!this._membersDef) {
this._membersDef = this._rpc({
model: 'mail.channel',
@@ -199,6 +189,7 @@ var Channel = ThreadWithCache.extend({
shadow: true
})
.then(function (members) {
+ self._members = members;
return members;
});
}
@@ -215,7 +206,7 @@ var Channel = ThreadWithCache.extend({
*/
getPreview: function () {
var result = this._super.apply(this, arguments);
- if (!this.isChat()) {
+ if (!this.isTwoUserThread()) {
result.imageSRC = '/web/image/mail.channel/' + this.getID() + '/image_small';
}
var lastMessage = this.getLastMessage();
@@ -223,7 +214,7 @@ var Channel = ThreadWithCache.extend({
author: lastMessage ? lastMessage.getDisplayedAuthor() : '',
body: lastMessage ? mailUtils.parseAndTransform(lastMessage.getBody(), mailUtils.inline) : '',
date: lastMessage ? lastMessage.getDate() : moment(),
- isAuthor: this.hasMessages() && this.getLastMessage().isAuthor(),
+ isMyselfAuthor: this.hasMessages() && this.getLastMessage().isMyselfAuthor(),
});
},
/**
@@ -252,15 +243,6 @@ var Channel = ThreadWithCache.extend({
this._needactionCounter++;
},
/**
- * Tells whether the current user is administrator of the channel.
- * Note that there is no administrator for chat channels
- *
- * @returns {boolean}
- */
- isAdministrator: function () {
- return session.uid === this._creatorUID && !this.isChat();
- },
- /**
* States whether the channel should be auto-selected on creation
*
* Note that this is not of the responsibility of the channel
@@ -282,18 +264,6 @@ var Channel = ThreadWithCache.extend({
return true;
},
/**
- * States whether this channel is a chat or not.
- * These types of channels are chat:
- * - direct messages (DM)
- * - livechat
- *
- * @override
- * @returns {boolean}
- */
- isChat: function () {
- return this._chat;
- },
- /**
* States whether the channel auto-subscribes some users in a group
*
* @returns {boolean}
@@ -308,81 +278,32 @@ var Channel = ThreadWithCache.extend({
* @returns {boolean}
*/
isModerated: function () {
- return this._moderation;
+ return this._isModerated;
},
/**
- * States whether the current user is moderator of this channel.
+ * Tells whether the current user is administrator of the channel.
+ * Note that there is no administrator for two-user channels
*
* @returns {boolean}
*/
- isModerator: function () {
- return this._isModerator;
- },
- /**
- * Marks this channel as read.
- * The last seen message will be the last message.
- * Resolved with the last seen message, only for non-mailbox channels
- *
- * @override
- * @returns {$.Promise<integer|undefined>} resolved with last message ID
- * seen in the channel, and when the channel has been marked as seen on
- * the server.
- */
- markAsRead: function () {
- if (this._unreadCounter > 0) {
- this.resetUnreadCounter();
- return this._throttleFetchSeen();
- }
- return this._super.apply(this, arguments);
+ isMyselfAdministrator: function () {
+ return session.uid === this._creatorUID && !this.isTwoUserThread();
},
/**
- * Prepare and send a message to the server on this channel
+ * States whether the current user is moderator of this channel.
*
- * @override
- * @param {Object} data data related to the new message
- * @returns {$.Promise<Object>} resolved when the message has been sent to
- * the server, with the object message that has been sent to the server.
+ * @returns {boolean}
*/
- postMessage: function (data) {
- var self = this;
- return this._super.apply(this, arguments).then(function (messageData) {
- _.extend(messageData, {
- message_type: 'comment',
- subtype: 'mail.mt_comment',
- command: data.command,
- });
- return self._rpc({
- model: 'mail.channel',
- method: data.command ? 'execute_command' : 'message_post',
- args: [self._id],
- kwargs: messageData,
- }).then(function () {
- return messageData;
- });
- });
+ isMyselfModerator: function () {
+ return this._isMyselfModerator;
},
/**
* Unsubscribes from channel
*
+ * @abstract
* @returns {$.Promise} resolve when unsubscribed
*/
- unsubscribe: function () {
- if (_.contains(['public', 'private'], this.getType())) {
- // unfollow channel
- return this._rpc({
- model: 'mail.channel',
- method: 'action_unfollow',
- args: [[this._id]],
- });
- } else {
- // unpin livechat
- return this._rpc({
- model: 'mail.channel',
- method: 'channel_pin',
- args: [this.getUUID(), false],
- });
- }
- },
+ unsubscribe: function () {},
/**
* Updates the internal state of the channel, and reflects the changes in
* the UI.
@@ -453,6 +374,47 @@ var Channel = ThreadWithCache.extend({
['need_moderation', '=', true],
['channel_ids', 'in', [this._id]]];
},
+ /**
+ * Marks this channel as read.
+ * The last seen message will be the last message.
+ * Resolved with the last seen message, only for non-mailbox channels
+ *
+ * @override
+ * @private
+ * @returns {$.Promise} resolved when message has been marked as read
+ */
+ _markAsRead: function () {
+ var superDef = this._super.apply(this, arguments);
+ var seenDef = this._throttleFetchSeen();
+ return $.when(superDef, seenDef);
+ },
+ /**
+ * Prepare and send a message to the server on this channel.
+ *
+ * @override
+ * @private
+ * @param {Object} data data related to the new message
+ * @returns {$.Promise<Object>} resolved when the message has been sent to
+ * the server, with the object message that has been sent to the server.
+ */
+ _postMessage: function (data) {
+ var self = this;
+ return this._super.apply(this, arguments).then(function (messageData) {
+ _.extend(messageData, {
+ message_type: 'comment',
+ subtype: 'mail.mt_comment',
+ command: data.command,
+ });
+ return self._rpc({
+ model: 'mail.channel',
+ method: data.command ? 'execute_command' : 'message_post',
+ args: [self._id],
+ kwargs: messageData,
+ }).then(function () {
+ return messageData;
+ });
+ });
+ },
});
return Channel;