summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/js/thread_windows/thread_window.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/mail/static/src/js/thread_windows/thread_window.js')
-rw-r--r--addons/mail/static/src/js/thread_windows/thread_window.js141
1 files changed, 94 insertions, 47 deletions
diff --git a/addons/mail/static/src/js/thread_windows/thread_window.js b/addons/mail/static/src/js/thread_windows/thread_window.js
index 1ff9417d127..1d38ee338d3 100644
--- a/addons/mail/static/src/js/thread_windows/thread_window.js
+++ b/addons/mail/static/src/js/thread_windows/thread_window.js
@@ -16,7 +16,10 @@ var _t = core._t;
*/
var ThreadWindow = AbstractThreadWindow.extend({
template: 'mail.ThreadWindow',
+ custom_events: AbstractThreadWindow.prototype.custom_events,
events: _.extend({}, AbstractThreadWindow.prototype.events, {
+ 'click .o_mail_thread': '_onThreadWindowFocus',
+ 'click .o_thread_composer': '_onThreadWindowFocus',
'click .o_thread_window_expand': '_onClickExpand',
}),
/**
@@ -25,7 +28,8 @@ var ThreadWindow = AbstractThreadWindow.extend({
* @override
* @param {mail.Manager} parent
* @param {mail.model.Thread} [thread = null] if not set, this is a "blank"
- * thread window. It lets us open a DM by providing the name of a chat.
+ * thread window. It lets us open a DM chat by providing the name of a
+ * user.
* @param {Object} [options={}]
* @param {boolean} [options.passively=false]
*/
@@ -34,11 +38,11 @@ var ThreadWindow = AbstractThreadWindow.extend({
// don't automatically mark unread messages as seen when at the bottom
// of the thread
- this._passive = this.options.passively;
+ this._passive = this.options.passively || false;
if (!this.hasThread()) {
// remembered partner ID of "blank" thread window in order to be
- // replaced with newly opened DM window
+ // replaced with newly opened DM chat window
this.directPartnerID = null;
}
},
@@ -54,10 +58,11 @@ var ThreadWindow = AbstractThreadWindow.extend({
var composerDef;
if (!this.hasThread()) {
this._startWithoutThread();
- } else if (this._needsComposer()) {
+ } else if (this.needsComposer()) {
var basicComposer = new BasicComposer(this, {
mentionPartnersRestricted: this._thread.getType() !== 'document_thread',
- isMini: true
+ isMini: true,
+ thread: this._thread,
});
basicComposer.on('post_message', this, this._postMessage);
basicComposer.once('input_focused', this, function () {
@@ -85,6 +90,8 @@ var ThreadWindow = AbstractThreadWindow.extend({
close: function () {
if (this.hasThread()) {
this._thread.close();
+ } else {
+ this.trigger_up('close_blank_thread_window');
}
},
/**
@@ -125,12 +132,66 @@ var ThreadWindow = AbstractThreadWindow.extend({
return this._passive;
},
/**
+ * States whether the input of the thread window should be displayed or not.
+ * This is based on the type of the thread:
+ *
+ * Do not display the input in the following cases:
+ *
+ * - no thread related to this window
+ * - window of a mailbox (temp: let us have mailboxes in window mode)
+ * - window of a thread with mass mailing
+ *
+ * Any other threads show the input in the window.
+ *
+ * @override
+ * @returns {boolean}
+ */
+ needsComposer: function () {
+ return this._super() && !this._thread.isMassMailing();
+ },
+ /**
* Turn the thread window in active mode, so that when the bottom of the
* thread is visible, it is automatically marked as read.
*/
removePassive: function () {
this._passive = false;
},
+ /**
+ * Set the thread window in passive mode, so that new received message will
+ * keep the thread window as unread until there is focus on the thread
+ * window.
+ */
+ setPassive: function () {
+ this._passive = true;
+ },
+ /**
+ * Update this thread window
+ *
+ * @param {Object} options
+ * @param {boolean} [options.keepBottom=false] if set, this thread window
+ * should scroll to the bottom if it was at the bottom before update
+ * @param {boolean} [options.passively=false] if set, this thread window
+ * becomes passive, so that it is marked as read only when the focus is
+ * on it.
+ */
+ update: function (options) {
+ var self = this;
+ if (options.passively) {
+ this.setPassive();
+ }
+ var bottomVisible = !this.isFolded() &&
+ !this.isHidden() &&
+ this.isAtBottom();
+ if (bottomVisible && !this.isPassive()) {
+ this._thread.markAsRead();
+ }
+ this._thread.fetchMessages().then(function () {
+ self.render();
+ if (bottomVisible && options.keepBottom) {
+ self.scrollToBottom();
+ }
+ });
+ },
//--------------------------------------------------------------------------
// Private
@@ -155,32 +216,12 @@ var ThreadWindow = AbstractThreadWindow.extend({
* @private
*/
_listenThreadWidget: function () {
- this.threadWidget
+ this._threadWidget
.on('redirect', this, this._onRedirect)
.on('redirect_to_channel', this, this._onRedirectToChannel)
.on('toggle_star_status', this, this._onToggleStarStatus);
},
/**
- * States whether the input of the thread window should be displayed or not.
- * This is based on the type of the thread:
- *
- * Do not display the input in the following cases:
- *
- * - no thread related to this window
- * - window of a mailbox (temp: let us have mailboxes in window mode)
- * - window of a thread with mass mailing
- *
- * Any other threads show the input in the window.
- *
- * @private
- * @returns {boolean}
- */
- _needsComposer: function () {
- return this.hasThread() &&
- (this._thread.getType() !== 'mailbox') &&
- !this._thread.isMassMailing();
- },
- /**
* Open this thread window.
* This private method exists only for the purpose of providing a callback
* function on redirect to a partner.
@@ -191,24 +232,6 @@ var ThreadWindow = AbstractThreadWindow.extend({
this.call('mail_service', 'openThreadWindow', this.getID());
},
/**
- * Post a message in the thread related to this window.
- * If this window has no thread, do nothing
- *
- * @override
- * @private
- * @param {Object} messageData
- */
- _postMessage: function (messageData) {
- var self = this;
- if (!this.hasThread()) {
- return;
- }
- this._thread.postMessage(messageData)
- .then(function () {
- self.threadWidget.scrollToBottom();
- });
- },
- /**
* @private
*/
_startWithoutThread: function () {
@@ -222,10 +245,10 @@ var ThreadWindow = AbstractThreadWindow.extend({
},
select: function (event, ui) {
// remember partner ID so that we can replace this window
- // with new DM window
+ // with new DM chat window
var partnerID = ui.item.id;
self.directPartnerID = partnerID;
- self.call('mail_service', 'openDmWindow', partnerID);
+ self.call('mail_service', 'openDMChatWindowFromBlankThreadWindow', partnerID);
},
})
.focus();
@@ -248,7 +271,7 @@ var ThreadWindow = AbstractThreadWindow.extend({
_onClickExpand: _.debounce(function (ev) {
var self = this;
ev.preventDefault();
- if (this._thread.getType() === 'document_thread') {
+ if (this.hasThread() && this._thread.getType() === 'document_thread') {
this.do_action({
type: 'ir.actions.act_window',
res_model: this._thread.getDocumentModel(),
@@ -306,6 +329,30 @@ var ThreadWindow = AbstractThreadWindow.extend({
}
},
/**
+ * Override it so that passive thread windows do not mark thread as read
+ * on scroll
+ *
+ * @override
+ * @private
+ */
+ _onScroll: function () {
+ if (this.isPassive()) {
+ return;
+ }
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * Called when focusing the thread window (click on thread or composer)
+ *
+ * @private
+ */
+ _onThreadWindowFocus: function () {
+ if (this.isPassive()) {
+ this.removePassive();
+ this._thread.markAsRead();
+ }
+ },
+ /**
* @private
* @param {integer} messageID
*/