[IMP] mail: open dm shortcut from in navbar dropdown
Allows to directly open a dm channel from a chat window, without coming back to Discuss.
This commit is contained in:
@@ -398,6 +398,13 @@ class Channel(models.Model):
|
||||
return channel.channel_info()[0]
|
||||
return False
|
||||
|
||||
@api.model
|
||||
def channel_get_and_minimize(self, partners_to):
|
||||
channel = self.channel_get(partners_to)
|
||||
if channel:
|
||||
self.channel_minimize(channel['uuid'])
|
||||
return channel
|
||||
|
||||
@api.model
|
||||
def channel_fold(self, uuid, state=None):
|
||||
""" Update the fold_state of the given session. In order to syncronize web browser
|
||||
|
||||
@@ -16,6 +16,7 @@ var preview_msg_max_size = 350; // optimal for native english speakers
|
||||
var MessageModel = new Model('mail.message', session.context);
|
||||
var ChannelModel = new Model('mail.channel', session.context);
|
||||
var UserModel = new Model('res.users', session.context);
|
||||
var PartnerModel = new Model('res.partner', session.context);
|
||||
|
||||
// Private model
|
||||
//----------------------------------------------------------------------------------
|
||||
@@ -621,7 +622,7 @@ function on_chat_session_notification (chat_session) {
|
||||
}
|
||||
|
||||
function on_presence_notification (data) {
|
||||
var dm = _.findWhere(channels, {direct_partner_id: data.id});
|
||||
var dm = chat_manager.get_dm_from_partner_id(data.id);
|
||||
if (dm) {
|
||||
dm.status = data.im_status;
|
||||
chat_manager.bus.trigger('update_dm_presence', dm);
|
||||
@@ -748,6 +749,10 @@ var chat_manager = {
|
||||
return _.findWhere(channels, {id: id});
|
||||
},
|
||||
|
||||
get_dm_from_partner_id: function (partner_id) {
|
||||
return _.findWhere(channels, {direct_partner_id: partner_id});
|
||||
},
|
||||
|
||||
all_history_loaded: function (channel, domain) {
|
||||
return get_channel_cache(channel, domain).all_history_loaded;
|
||||
},
|
||||
@@ -824,6 +829,9 @@ var chat_manager = {
|
||||
}
|
||||
return channel_defs[channel_id];
|
||||
},
|
||||
open_and_detach_dm: function (partner_id) {
|
||||
return ChannelModel.call('channel_get_and_minimize', [[partner_id]]).then(add_channel);
|
||||
},
|
||||
|
||||
unsubscribe: function (channel) {
|
||||
var def;
|
||||
@@ -840,11 +848,14 @@ var chat_manager = {
|
||||
var channel = this.get_channel(channel_id);
|
||||
ChannelModel.call("channel_fold", [], {uuid : channel.uuid, state : "closed"});
|
||||
},
|
||||
fold_channel: function (channel_id) {
|
||||
var channel = this.get_channel(channel_id);
|
||||
return ChannelModel.call("channel_fold", [], {uuid : channel.uuid}).then(function () {
|
||||
channel.is_folded = !channel.is_folded;
|
||||
});
|
||||
fold_channel: function (channel_id, folded) {
|
||||
var args = {
|
||||
uuid: this.get_channel(channel_id).uuid,
|
||||
};
|
||||
if (_.isBoolean(folded)) {
|
||||
args.state = folded ? 'folded' : 'open';
|
||||
}
|
||||
return ChannelModel.call("channel_fold", [], args);
|
||||
},
|
||||
/**
|
||||
* Special redirection handling for given model and id
|
||||
@@ -918,6 +929,20 @@ var chat_manager = {
|
||||
get_message_body_preview: function (message_body) {
|
||||
return parse_and_transform(message_body, inline);
|
||||
},
|
||||
|
||||
search_partner: function (search_val) {
|
||||
return PartnerModel.call('im_search', [search_val, 20]).then(function(result) {
|
||||
var values = [];
|
||||
_.each(result, function(user) {
|
||||
var escaped_name = _.escape(user.name);
|
||||
values.push(_.extend(user, {
|
||||
'value': escaped_name,
|
||||
'label': escaped_name,
|
||||
}));
|
||||
});
|
||||
return values;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// Initialization
|
||||
|
||||
@@ -107,8 +107,8 @@ return Widget.extend({
|
||||
this.trigger("close_chat_session");
|
||||
},
|
||||
on_click_fold: function () {
|
||||
this.trigger("fold_channel", this.channel_id);
|
||||
this.toggle_fold();
|
||||
this.trigger("fold_channel", this.channel_id, this.folded);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -272,9 +272,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
this.$('.o_mail_add_channel[data-type=dm]').find("input").autocomplete({
|
||||
source: function(request, response) {
|
||||
self.last_search_val = _.escape(request.term);
|
||||
self.do_search_partner(self.last_search_val).done(function(result){
|
||||
response(result);
|
||||
});
|
||||
chat_manager.search_partner(self.last_search_val).done(response);
|
||||
},
|
||||
select: function(event, ui) {
|
||||
var partner_id = ui.item.id;
|
||||
@@ -319,21 +317,6 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
});
|
||||
},
|
||||
|
||||
do_search_partner: function (search_val) {
|
||||
var Partner = new Model("res.partner");
|
||||
return Partner.call('im_search', [search_val, 20]).then(function(result){
|
||||
var values = [];
|
||||
_.each(result, function(user){
|
||||
var escaped_name = _.escape(user.name);
|
||||
values.push(_.extend(user, {
|
||||
'value': escaped_name,
|
||||
'label': escaped_name,
|
||||
}));
|
||||
});
|
||||
return values;
|
||||
});
|
||||
},
|
||||
|
||||
set_channel: function (channel) {
|
||||
var self = this;
|
||||
// Store scroll position of previous channel
|
||||
|
||||
@@ -22,6 +22,7 @@ var MessagingMenu = Widget.extend({
|
||||
events: {
|
||||
"click": "on_click",
|
||||
"click .o_filter_button": "on_click_filter_button",
|
||||
"click .o_new_message": "on_click_new_message",
|
||||
"click .o_mail_channel_preview": "on_click_channel",
|
||||
"click .o_redirect_to_discuss": "on_click_redirect_to_discuss",
|
||||
},
|
||||
@@ -99,6 +100,9 @@ var MessagingMenu = Widget.extend({
|
||||
this.filter = $target.data('filter');
|
||||
this.render_channels_preview();
|
||||
},
|
||||
on_click_new_message: function () {
|
||||
chat_manager.bus.trigger('open_chat');
|
||||
},
|
||||
on_click_channel: function (event) {
|
||||
var channel_id = $(event.currentTarget).data('channel_id');
|
||||
var channel = chat_manager.get_channel(channel_id);
|
||||
|
||||
@@ -2,18 +2,20 @@ odoo.define('mail.window_manager', function (require) {
|
||||
"use strict";
|
||||
|
||||
var chat_manager = require('mail.chat_manager');
|
||||
var ChatWindow = require('mail.ChatWindow');
|
||||
var ExtendedChatWindow = require('mail.ExtendedChatWindow');
|
||||
|
||||
var core = require('web.core');
|
||||
var utils = require('web.utils');
|
||||
var web_client = require('web.web_client');
|
||||
|
||||
var _t = core._t;
|
||||
var QWeb = core.qweb;
|
||||
|
||||
// chat window management
|
||||
//----------------------------------------------------------------
|
||||
var CHAT_WINDOW_WIDTH = 300 + 5; // 5 pixels between windows
|
||||
var chat_sessions = [];
|
||||
var new_chat_session;
|
||||
var display_state = {
|
||||
hidden_sessions: [],
|
||||
hidden_unread_counter: 0, // total number of unread msgs in hidden chat windows
|
||||
@@ -22,14 +24,24 @@ var display_state = {
|
||||
windows_dropdown_is_open: false, // used to keep dropdown open when closing chat windows
|
||||
};
|
||||
|
||||
function add_chat_session (chat_session) {
|
||||
// adds chat_session such that it will be the left-most visible window
|
||||
compute_available_slots(chat_sessions.length+1);
|
||||
chat_sessions.splice(display_state.nb_slots-1, 0, chat_session);
|
||||
}
|
||||
|
||||
function open_chat (session) {
|
||||
if (!session) {
|
||||
open_chat_without_session();
|
||||
return;
|
||||
}
|
||||
var chat_session = _.findWhere(chat_sessions, {id: session.id});
|
||||
if (!chat_session) {
|
||||
chat_session = {
|
||||
id: session.id,
|
||||
uuid: session.uuid,
|
||||
name: session.name,
|
||||
window: new ChatWindow(web_client, session.id, session.name, session.is_folded, session.unread_counter),
|
||||
window: new ExtendedChatWindow(web_client, session.id, session.name, session.is_folded, session.unread_counter),
|
||||
};
|
||||
chat_session.window.on("close_chat_session", null, function () {
|
||||
close_chat(chat_session);
|
||||
@@ -39,8 +51,8 @@ function open_chat (session) {
|
||||
chat_manager.toggle_star_status(message_id);
|
||||
});
|
||||
|
||||
chat_session.window.on("fold_channel", null, function (channel_id) {
|
||||
chat_manager.fold_channel(channel_id);
|
||||
chat_session.window.on("fold_channel", null, function (channel_id, folded) {
|
||||
chat_manager.fold_channel(channel_id, folded);
|
||||
});
|
||||
|
||||
chat_session.window.on("post_message", null, function (message, channel_id) {
|
||||
@@ -64,13 +76,17 @@ function open_chat (session) {
|
||||
}
|
||||
});
|
||||
|
||||
// insert chat_session such that it will be the right-most visible window
|
||||
compute_available_slots(chat_sessions.length+1);
|
||||
chat_sessions.splice(display_state.nb_slots-1, 0, chat_session);
|
||||
var remove_new_chat = false;
|
||||
if (new_chat_session && new_chat_session.partner_id && new_chat_session.partner_id === session.direct_partner_id) {
|
||||
chat_sessions[_.indexOf(chat_sessions, new_chat_session)] = chat_session;
|
||||
remove_new_chat = true;
|
||||
} else {
|
||||
add_chat_session(chat_session);
|
||||
}
|
||||
|
||||
chat_session.window.appendTo($('body'))
|
||||
.then(reposition_windows)
|
||||
.then(function () {
|
||||
reposition_windows({remove_new_chat: remove_new_chat});
|
||||
return chat_manager.get_messages({channel_id: chat_session.id});
|
||||
}).then(function (messages) {
|
||||
chat_session.window.render(messages);
|
||||
@@ -88,19 +104,60 @@ function open_chat (session) {
|
||||
}
|
||||
}
|
||||
|
||||
function close_chat (chat_session) {
|
||||
var session = _.find(chat_sessions, {id: chat_session.id});
|
||||
if (session) {
|
||||
chat_sessions = _.without(chat_sessions, session);
|
||||
session.window.destroy();
|
||||
reposition_windows();
|
||||
function open_chat_without_session () {
|
||||
if (!new_chat_session) {
|
||||
new_chat_session = {
|
||||
id: '_open',
|
||||
window: new ExtendedChatWindow(web_client, undefined, _t('New message'), false, 0, {thread_less: true}),
|
||||
};
|
||||
new_chat_session.window.on("close_chat_session", null, close_new_chat);
|
||||
new_chat_session.window.on('open_dm_session', null, function (partner_id) {
|
||||
new_chat_session.partner_id = partner_id;
|
||||
var dm = chat_manager.get_dm_from_partner_id(partner_id);
|
||||
if (!dm) {
|
||||
chat_manager.open_and_detach_dm(partner_id);
|
||||
} else {
|
||||
var dm_session = _.findWhere(chat_sessions, {id: dm.id});
|
||||
if (!dm_session) {
|
||||
chat_manager.detach_channel(dm);
|
||||
} else {
|
||||
close_chat(dm_session);
|
||||
dm.is_folded = false;
|
||||
open_chat(dm);
|
||||
}
|
||||
}
|
||||
});
|
||||
add_chat_session(new_chat_session);
|
||||
new_chat_session.window.appendTo($('body')).then(reposition_windows);
|
||||
} else {
|
||||
if (new_chat_session.window.is_hidden) {
|
||||
make_session_visible(new_chat_session);
|
||||
} else if (new_chat_session.window.folded) {
|
||||
new_chat_session.window.toggle_fold(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function close_chat (chat_session) {
|
||||
chat_sessions = _.without(chat_sessions, chat_session);
|
||||
chat_session.window.destroy();
|
||||
reposition_windows();
|
||||
}
|
||||
|
||||
function close_new_chat () {
|
||||
chat_sessions = _.without(chat_sessions, new_chat_session);
|
||||
reposition_windows({remove_new_chat: true});
|
||||
}
|
||||
|
||||
function destroy_new_chat () {
|
||||
new_chat_session.window.destroy();
|
||||
new_chat_session = undefined;
|
||||
}
|
||||
|
||||
function toggle_fold_chat (channel) {
|
||||
var session = _.find(chat_sessions, {id: channel.id});
|
||||
if (session) {
|
||||
session.window.toggle_fold();
|
||||
session.window.toggle_fold(channel.is_folded);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +173,10 @@ function compute_available_slots (nb_windows) {
|
||||
display_state.space_left = space_left;
|
||||
}
|
||||
|
||||
var reposition_windows = _.debounce(function () {
|
||||
var reposition_windows = function (options) {
|
||||
if (options && options.remove_new_chat) {
|
||||
destroy_new_chat();
|
||||
}
|
||||
compute_available_slots(chat_sessions.length);
|
||||
var hidden_sessions = [];
|
||||
var hidden_unread_counter = 0;
|
||||
@@ -161,7 +221,7 @@ var reposition_windows = _.debounce(function () {
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
function make_session_visible (session) {
|
||||
utils.swap(chat_sessions, session, chat_sessions[display_state.nb_slots-1]);
|
||||
@@ -205,7 +265,12 @@ function update_sessions (message, scrollBottom) {
|
||||
|
||||
core.bus.on('web_client_ready', null, function () {
|
||||
chat_manager.bus.on('open_chat', null, open_chat);
|
||||
chat_manager.bus.on('close_chat', null, close_chat);
|
||||
chat_manager.bus.on('close_chat', null, function (channel) {
|
||||
var session = _.find(chat_sessions, {id: channel.id});
|
||||
if (session) {
|
||||
close_chat(session);
|
||||
}
|
||||
});
|
||||
chat_manager.bus.on('channel_toggle_fold', null, toggle_fold_chat);
|
||||
|
||||
chat_manager.bus.on('new_message', null, function (message) {
|
||||
@@ -265,7 +330,38 @@ core.bus.on('web_client_ready', null, function () {
|
||||
}
|
||||
});
|
||||
|
||||
core.bus.on('resize', null, reposition_windows);
|
||||
core.bus.on('resize', null, _.debounce(reposition_windows, 100));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// FIXME: move this to its own file in master
|
||||
odoo.define('mail.ExtendedChatWindow', function (require) {
|
||||
"use strict";
|
||||
|
||||
var chat_manager = require('mail.chat_manager');
|
||||
var ChatWindow = require('mail.ChatWindow');
|
||||
|
||||
return ChatWindow.extend({
|
||||
template: "mail.ExtendedChatWindow",
|
||||
start: function () {
|
||||
var self = this;
|
||||
return this._super().then(function () {
|
||||
if (self.options.thread_less) {
|
||||
self.$el.addClass('o_thread_less');
|
||||
self.$('.o_chat_search_input input')
|
||||
.autocomplete({
|
||||
source: function(request, response) {
|
||||
chat_manager.search_partner(request.term).done(response);
|
||||
},
|
||||
select: function(event, ui) {
|
||||
self.trigger('open_dm_session', ui.item.id);
|
||||
},
|
||||
})
|
||||
.focus();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -109,3 +109,24 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: move this to its own file in master
|
||||
.o_chat_window.o_thread_less {
|
||||
.o_chat_search_input {
|
||||
.o-flex-display();
|
||||
padding: 5px;
|
||||
> span {
|
||||
.o-flex(0, 0, auto);
|
||||
}
|
||||
> input {
|
||||
margin-left: 5px;
|
||||
.o-flex(1, 1, 100%);
|
||||
}
|
||||
}
|
||||
.o_chat_content {
|
||||
background-color: lightgray;
|
||||
}
|
||||
.o_chat_input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,13 +279,16 @@
|
||||
}
|
||||
|
||||
.o_filter_button,
|
||||
.o_new_message,
|
||||
.o_redirect_to_discuss {
|
||||
.btn-link;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.o_mail_navbar_dropdown_top {
|
||||
.o-flex-display();
|
||||
.o-flex(0, 0, auto);
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid lightgray;
|
||||
|
||||
.o_filter_button {
|
||||
|
||||
@@ -17,6 +17,16 @@
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- FIXME: move this to its own file in master -->
|
||||
<t t-name="mail.ExtendedChatWindow" t-extend="mail.ChatWindow">
|
||||
<t t-jquery=".o_chat_header" t-operation="after">
|
||||
<div t-if="widget.options.thread_less" class="o_chat_search_input">
|
||||
<span> To: </span>
|
||||
<input type="text"/>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="mail.ChatWindowsDropdown">
|
||||
<div t-attf-class="o_chat_window o_chat_window_dropdown dropup #{open ? 'open' : ''}">
|
||||
<span class="o_chat_window_dropdown_toggler dropdown-toggle" data-toggle="dropdown">
|
||||
@@ -29,7 +39,7 @@
|
||||
<t t-foreach="sessions" t-as="session">
|
||||
<li class="o_chat_header" t-att-data-session-id="session.id">
|
||||
<t t-call="mail.ChatWindowHeaderContent">
|
||||
<t t-set="title" t-value="session.name"/>
|
||||
<t t-set="title" t-value="session.window.title"/>
|
||||
<t t-set="unread_counter" t-value="session.window.unread_msgs"/>
|
||||
</t>
|
||||
</li>
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
</a>
|
||||
<ul class="o_mail_navbar_dropdown dropdown-menu" role="menu">
|
||||
<li class="o_mail_navbar_dropdown_top">
|
||||
<button type="button" class="btn btn-sm o_filter_button o_selected"> All </button>
|
||||
<button type="button" class="btn btn-sm o_filter_button" data-filter='chat'> Chat </button>
|
||||
<button type="button" class="btn btn-sm o_filter_button" data-filter='channels'> Channels </button>
|
||||
<div>
|
||||
<button type="button" class="btn btn-sm o_filter_button o_selected"> All </button>
|
||||
<button type="button" class="btn btn-sm o_filter_button" data-filter='chat'> Chat </button>
|
||||
<button type="button" class="btn btn-sm o_filter_button" data-filter='channels'> Channels </button>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm o_new_message"> New message </button>
|
||||
</li>
|
||||
<li class="o_mail_navbar_dropdown_channels"/>
|
||||
<li class="o_mail_navbar_dropdown_bottom">
|
||||
|
||||
Reference in New Issue
Block a user