summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/js/models/threads/thread.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/thread.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/thread.js')
-rw-r--r--addons/mail/static/src/js/models/threads/thread.js155
1 files changed, 63 insertions, 92 deletions
diff --git a/addons/mail/static/src/js/models/threads/thread.js b/addons/mail/static/src/js/models/threads/thread.js
index 5fcd0285a82..c9dda28dd93 100644
--- a/addons/mail/static/src/js/models/threads/thread.js
+++ b/addons/mail/static/src/js/models/threads/thread.js
@@ -5,7 +5,6 @@ var emojis = require('mail.emojis');
var AbstractThread = require('mail.model.AbstractThread');
var mailUtils = require('mail.utils');
-var Mixins = require('web.mixins');
var ServicesMixin = require('web.ServicesMixin');
/**
@@ -15,7 +14,7 @@ var ServicesMixin = require('web.ServicesMixin');
*
* In particular, channels and mailboxes are two different kinds of threads.
*/
-var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
+var Thread = AbstractThread.extend(ServicesMixin, {
/**
* @override
@@ -27,15 +26,9 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
* @param {string} [params.data.type]
*/
init: function (params) {
- Mixins.EventDispatcherMixin.init.call(this, arguments);
- this.setParent(params.parent);
this._super.apply(this, arguments);
// threads are not detached by default
this._detached = false;
- // if this._massMailing is set, display subject on messages, use
- // extended composer and show "Send by messages by email" on discuss
- // sidebar
- this._massMailing = false;
// on 1st request to getPreview, fetch data if incomplete. Otherwise it
// means that there is no message in this channel.
this._previewed = false;
@@ -49,13 +42,6 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
//--------------------------------------------------------------------------
/**
- * Add a message to this thread.
- *
- * @abstract
- * @param {mail.model.Message} message
- */
- addMessage: function (message) {},
- /**
* Updates the _detached state of the thread. Must be overriden to reflect
* the new state in the interface.
*/
@@ -140,7 +126,7 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
return {
id: this.getID(),
imageSRC: '/mail/static/src/img/smiley/avatar.jpg',
- isChat: this.isChat(),
+ isTwoUserThread: this.isTwoUserThread(),
status: this.getStatus(),
title: this.getName(),
unreadCounter: this.getUnreadCounter(),
@@ -189,16 +175,6 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
*/
incrementNeedactionCounter: function () {},
/**
- * Increment the unread counter of this thread by 1 unit, and warn that the
- * counter has been changed.
- *
- * @override
- */
- incrementUnreadCounter: function () {
- this._super.apply(this, arguments);
- this._warnUpdatedUnreadCounter();
- },
- /**
* States whether the thread should be auto-selected on creation
*
* Note that this is not of the responsibility of the thread: it only
@@ -223,17 +199,6 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
return false;
},
/**
- * States whether this thread is a chat or not. In particular, public and
- * private channels are not chat, but DMs and Livechats are chats. Chats
- * are threads used for communication between two users.
- * By default, any thread is not a chat
- *
- * @returns {boolean}
- */
- isChat: function () {
- return false;
- },
- /**
* States whether this thread is detached or not.
* A thread that is detached must have a thread window linked to itself.
*
@@ -256,10 +221,12 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
* This is a server-side setting, that determine the type of composer that
* is used (basic or extended composer).
*
+ * By default, thread have not mass-mailings feature set.
+ *
* @return {boolean}
*/
isMassMailing: function () {
- return this._massMailing;
+ return false;
},
/**
@@ -277,7 +244,18 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
*
* @returns {boolean}
*/
- isModerator: function () {
+ isMyselfModerator: function () {
+ return false;
+ },
+ /**
+ * States whether this is a two-user thread or not. In particular, public
+ * and private channels are not two-user threads, but DMs and Livechats are
+ * two-user threads. Two-user threads are used for communication between
+ * two users. By default, any thread is not two-user thread.
+ *
+ * @returns {boolean}
+ */
+ isTwoUserThread: function () {
return false;
},
/**
@@ -294,29 +272,61 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
markAsPreviewed: function () {
this._previewed = true;
},
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
/**
- * Mark the thread as read, which resets the unread counter to 0.
- *
- * @returns {$.Promise} resolved
+ * @abstract
+ * @private
+ * @return {$.Promise}
*/
- markAsRead: function () {
- if (this._unreadCounter > 0) {
- this.resetUnreadCounter();
- }
+ _fetchMessages: function () {
return $.when();
},
/**
+ * Replace character representations of emojis by their unicode
+ * representation in the provided HTML string. Note that the provided html
+ * string is altered by this function.
+ *
+ * @param {string} htmlString
+ * @returns {string}
+ */
+ _generateEmojis: function (htmlString) {
+ _.each(emojis, function (emoji) {
+ _.each(emoji.sources, function (source) {
+ var escapedSource = String(source).replace(/([.*+?=^!:${}()|[\]/\\])/g, '\\$1');
+ var regexp = new RegExp("(\\s|^)(" + escapedSource + ")(?=\\s|$)", 'g');
+ htmlString = htmlString.replace(regexp, '$1' + emoji.unicode);
+ });
+ });
+ return htmlString;
+ },
+ /**
+ * Increment the unread counter of this thread by 1 unit, and warn that the
+ * counter has been changed.
+ *
+ * @override
+ * @private
+ */
+ _incrementUnreadCounter: function () {
+ this._super.apply(this, arguments);
+ this._warnUpdatedUnreadCounter();
+ },
+ /**
* Post a message on the thread.
*
* This method must be completed by concrete threads,
* As it currently only pre-process the messages at the moment.
*
* @abstract
+ * @private
* @param {Object} data
* @returns {$.Promise<Object>} resolved with the message object to be sent
* to the server
*/
- postMessage: function (data) {
+ _postMessage: function (data) {
// This message will be received from the mail composer as html content
// subtype but the urls will not be linkified. If the mail composer
// takes the responsibility to linkify the urls we end up with double
@@ -334,58 +344,18 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
if ('subject' in data) {
messageData.subject = data.subject;
}
- return $.when(messageData);
- },
- /**
- * Overrides the method so that it also warns that the counter has been
- * changed on this thread.
- *
- * @override
- * @private
- */
- resetUnreadCounter: function () {
- this._super.apply(this, arguments);
- this._warnUpdatedUnreadCounter();
- },
-
- //--------------------------------------------------------------------------
- // Private
- //--------------------------------------------------------------------------
-
- /**
- * @abstract
- * @private
- * @return {$.Promise}
- */
- _fetchMessages: function () {
- return $.when();
- },
- /**
- * Replace character representations of emojis by their unicode
- * representation in the provided HTML string. Note that the provided html
- * string is altered by this function.
- *
- * @param {string} htmlString
- * @returns {string}
- */
- _generateEmojis: function (htmlString) {
- _.each(emojis, function (emoji) {
- _.each(emoji.sources, function (source) {
- var escapedSource = String(source).replace(/([.*+?=^!:${}()|[\]/\\])/g, '\\$1');
- var regexp = new RegExp("(\\s|^)(" + escapedSource + ")(?=\\s|$)", 'g');
- htmlString = htmlString.replace(regexp, '$1' + emoji.unicode);
- });
+ return this._super.apply(this, arguments).then(function () {
+ return $.when(messageData);
});
- return htmlString;
},
/**
- * Warn on the chat bus that the unread counter has been updated
+ * Warn on the mail bus that the unread counter has been updated
*
+ * @override
* @private
*/
_warnUpdatedUnreadCounter: function () {
- this.call('mail_service', 'getMailBus')
- .trigger('update_thread_unread_counter', this);
+ this.call('mail_service', 'getMailBus').trigger('update_thread_unread_counter', this);
},
/**
* Warn other mail components that the window state of this thread has
@@ -393,6 +363,7 @@ var Thread = AbstractThread.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
*
* @private
* @param {Object} [options={}]
+ * @param {boolean} [options.passively=false]
*/
_warnUpdatedWindowState: function (options) {
options = options || {};