[FIX] mail: redirection handling in chat windows

- clicking on a channel mention (or a user) from a chat window opens a new chat
  window for that channel
- clicking on any other link in a chat window correctly opens the corresponding
  document

2 minor changes were required:
- use do_show() instead of on_reverse_breadcrumb() to update control panel and
  url in client action, as other actions can be stacked over the client action,
  e.g. by clicking on a document link in a chat window. In that case, the
  on_reverse_breadcrumb callback wouldn't be set, and thus the control panel and
  url wouldn't be updated by coming back to client action using the breadcrumbs.
- channel_join() now checks whether or not the channel has already been joined
  (i.e. if it is in the JS cache) before performing the RPC. This check was
  performed by each caller, so this simplifies the code.
This commit is contained in:
Aaron Bohy
2015-12-03 11:21:47 +01:00
parent 6e96da6255
commit 33ac65c805
5 changed files with 80 additions and 79 deletions
+47 -8
View File
@@ -15,6 +15,7 @@ var preview_msg_max_size = 50;
var MessageModel = new Model('mail.message', session.context);
var ChannelModel = new Model('mail.channel', session.context);
var UserModel = new Model('res.users', session.context);
// Private model
//----------------------------------------------------------------------------------
@@ -399,7 +400,7 @@ function on_needaction_notification (message) {
function on_channel_notification (message) {
var def;
if ((message.channel_ids.length === 1) && !chat_manager.get_channel(message.channel_ids[0])) {
if (message.channel_ids.length === 1) {
def = chat_manager.join_channel(message.channel_ids[0], {autoswitch: false});
} else {
def = $.when();
@@ -638,15 +639,21 @@ var chat_manager = {
},
join_channel: function (channel_id, options) {
if (channel_id in channel_defs) {
// prevents concurrent calls to channel_join_and_get_info
return channel_defs[channel_id];
}
var def = ChannelModel
.call('channel_join_and_get_info', [[channel_id]])
.then(function (result) {
add_channel(result, options);
});
channel_defs[channel_id] = def;
return def;
var channel = this.get_channel(channel_id);
if (channel) {
// channel already joined
channel_defs[channel_id] = $.when(channel);
} else {
channel_defs[channel_id] = ChannelModel
.call('channel_join_and_get_info', [[channel_id]])
.then(function (result) {
return add_channel(result, options);
});
}
return channel_defs[channel_id];
},
unsubscribe: function (channel) {
@@ -671,6 +678,38 @@ var chat_manager = {
channel.is_folded = !channel.is_folded;
});
},
/**
* Special redirection handling for given model and id
*
* If the model is res.partner, and there is a user associated with this
* partner which isn't the current user, open the DM with this user.
* Otherwhise, open the record's form view, if this is not the current user's.
*/
redirect: function (res_model, res_id, dm_redirection_callback) {
var self = this;
var redirect_to_document = function (res_model, res_id) {
web_client.do_action({
type:'ir.actions.act_window',
view_type: 'form',
view_mode: 'form',
res_model: res_model,
views: [[false, 'form']],
res_id: res_id,
});
};
if (res_model === "res.partner") {
var domain = [["partner_id", "=", res_id]];
UserModel.call("search", [domain]).then(function (user_ids) {
if (user_ids.length && user_ids[0] !== session.uid) {
self.create_channel(res_id, 'dm').then(dm_redirection_callback || function () {});
} else if (!user_ids.length) {
redirect_to_document(res_model, res_id);
}
});
} else {
redirect_to_document(res_model, res_id);
}
},
};
// Initialization
+5 -5
View File
@@ -37,9 +37,9 @@ return Widget.extend({
display_needactions: false,
display_stars: this.options.display_stars,
});
this.thread.on('toggle_star_status', this, function (message_id) {
this.trigger('toggle_star_status', message_id);
});
this.thread.on('toggle_star_status', null, this.trigger.bind(this, 'toggle_star_status'));
this.thread.on('redirect_to_channel', null, this.trigger.bind(this, 'redirect_to_channel'));
this.thread.on('redirect', null, this.trigger.bind(this, 'redirect'));
this.fold();
var def = this.thread.appendTo(this.$content);
@@ -67,8 +67,8 @@ return Widget.extend({
height: this.folded ? "28px" : "333px"
});
},
toggle_fold: function () {
this.folded = !this.folded;
toggle_fold: function (fold) {
this.folded = _.isBoolean(fold) ? fold : !this.folded;
if (!this.folded) {
this.unread_msgs = 0;
this.trigger('messages_read');
+1 -6
View File
@@ -781,12 +781,7 @@ var Chatter = form_common.AbstractField.extend({
on_channel_redirect: function (channel_id) {
var self = this;
var def;
var channel = chat_manager.get_channel(channel_id);
// If not registered to 'channel' yet, do it
if (!channel) {
def = chat_manager.join_channel(channel_id);
}
var def = chat_manager.join_channel(channel_id);
$.when(def).then(function () {
// Execute Discuss client action with 'channel' as default channel
var discuss_ids = chat_manager.get_discuss_ids();
+14 -60
View File
@@ -179,14 +179,11 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
});
this.$buttons.on('click', '.o_mail_chat_button_unstar_all', chat_manager.unstar_all);
this.thread.on('redirect', this, this.on_redirect);
this.thread.on('redirect', this, function (res_model, res_id) {
chat_manager.redirect(res_model, res_id, this.set_channel.bind(this));
});
this.thread.on('redirect_to_channel', this, function (channel_id) {
var channel = chat_manager.get_channel(channel_id);
if (channel) {
this.set_channel(channel);
} else {
chat_manager.join_channel(channel_id);
}
chat_manager.join_channel(channel_id).then(this.set_channel.bind(this));
});
this.thread.on('load_more_messages', this, this.load_more_messages);
this.thread.on('mark_as_read', this, function (message_id) {
@@ -364,7 +361,6 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
self.$buttons
.find('.o_mail_chat_button_unstar_all')
.toggle(channel.id === "channel_starred");
self.update_cp();
self.$('.o_chat_composer').toggle(channel.type !== 'static');
@@ -382,6 +378,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
self.$('.o_mail_chat_sidebar').hide();
}
self.update_cp();
self.action_manager.do_push_state({
action: self.action.id,
active_id: self.channel.id,
@@ -478,6 +475,15 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
});
},
do_show: function () {
this._super.apply(this, arguments);
this.update_cp();
this.action_manager.do_push_state({
action: this.action.id,
active_id: this.channel.id,
});
},
on_search: function (domains) {
var result = pyeval.sync_eval_domains_and_contexts({
domains: domains
@@ -487,56 +493,6 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
this.fetch_and_render_thread();
},
/**
* Callback performed on o_mail_redirect element clicked
*
* If the model is res.partner, and there is a user associated with this
* partner which isn't the current user, open the DM with this user.
* Otherwhise, open the record's form view.
*/
on_redirect: function (res_model, res_id) {
var self = this;
var redirect_to_document = function (res_model, res_id) {
self.action_manager.do_push_state({
model: res_model,
id: res_id,
});
self.do_action({
type:'ir.actions.act_window',
view_type: 'form',
view_mode: 'form',
res_model: res_model,
views: [[false, 'form']],
res_id: res_id,
}, {
on_reverse_breadcrumb: self.on_reverse_breadcrumb,
});
};
if (res_model === "res.partner") {
var domain = [["partner_id", "=", res_id]];
new Model('res.users').call("search", [domain]).then(function (user_ids) {
if (user_ids.length && user_ids[0] !== session.uid) {
chat_manager.create_channel(res_id, 'dm').then(function (channel) {
if (!self.channel || self.channel.id !== channel.id) {
self.set_channel(channel);
}
});
} else {
redirect_to_document(res_model, res_id);
}
});
} else {
redirect_to_document(res_model, res_id);
}
},
on_reverse_breadcrumb: function () {
this.update_cp(); // do not reload the client action, just display it, but a refresh of the control panel is needed.
this.action_manager.do_push_state({
action: this.action.id,
active_id: this.channel.id,
});
},
on_post_message: function (message) {
message.channel_id = this.channel.id;
chat_manager
@@ -604,8 +560,6 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
res_id: this.channel.id,
views: [[false, 'form']],
target: 'current'
}, {
on_reverse_breadcrumb: this.on_reverse_breadcrumb,
});
},
});
@@ -43,6 +43,19 @@ function open_chat (session) {
chat_session.window.on("messages_read", null, function () {
chat_manager.mark_channel_as_seen(channel);
});
chat_session.window.on("redirect", null, function (res_model, res_id) {
chat_manager.redirect(res_model, res_id, open_chat);
});
chat_session.window.on("redirect_to_channel", null, function (channel_id) {
var session = _.findWhere(chat_sessions, {id: channel_id});
if (!session) {
chat_manager.join_channel(channel_id).then(function (channel) {
chat_manager.detach_channel(channel);
});
} else {
session.window.toggle_fold(false);
}
});
chat_sessions.push(chat_session);
chat_session.window.appendTo($('body'))