diff options
| author | Alexandre Kühn <aku@odoo.com> | 2018-08-11 20:30:51 +0200 |
|---|---|---|
| committer | Alexandre Kühn <aku@odoo.com> | 2018-08-13 14:17:27 +0200 |
| commit | f2302dfb27dd7f6a0dee7c65ab75b62a01706264 (patch) | |
| tree | d58fef9e2e8a5b98c0680f28fc92e24992236029 /addons/mail/static/src/js/models/threads/channel.js | |
| parent | 3de97f168956a7c22c3af6b72950cf28554f4139 (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.js | 162 |
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; |
