diff options
Diffstat (limited to 'addons/mail/static/src/js/mail_chat_backend.js')
| -rw-r--r-- | addons/mail/static/src/js/mail_chat_backend.js | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/addons/mail/static/src/js/mail_chat_backend.js b/addons/mail/static/src/js/mail_chat_backend.js new file mode 100644 index 00000000000..cd1cc00fdf2 --- /dev/null +++ b/addons/mail/static/src/js/mail_chat_backend.js @@ -0,0 +1,301 @@ +odoo.define('im_chat.im_chat', function (require) { +"use strict"; + +// to do: make this work in website + +var bus = require('bus.bus'); +var core = require('web.core'); +var data = require('web.data'); +var Model = require('web.DataModel'); +var session = require('web.session'); +var SystrayMenu = require('web.SystrayMenu'); +var utils = require('web.utils'); +var web_client = require('web.web_client'); +var Widget = require('web.Widget'); +var im_chat_common = require('im_chat.im_chat_common'); + +var _t = core._t; +var QWeb = core.qweb; + +var USERS_LIMIT = 20; + + +// ########## CONVERSATION extentions ############### + +im_chat_common.ConversationManager.include({ + _message_receive: function(message){ + var self = this; + var session_id = message.to_id[0]; + var conv = this.sessions[message.to_id[1]]; + if(!conv){ + // fetch the session, and init it with the message + var def_session = new Model("im_chat.session").call("session_info", [], {"ids" : [session_id]}).then(function(session){ + conv = self.session_apply(session, {'force_open': true}); + conv.message_receive(message); + }); + }else{ + this._super(message); + } + }, +}); + +im_chat_common.Conversation.include({ + // user actions + prepare_action_menu: function(){ + this._super(); + this._add_action(_t('Shortcuts'), 'im_chat_option_shortcut', 'fa fa-info-circle', this.action_shorcode); + this._add_action(_t('Quit discussion'), 'im_chat_option_quit', 'fa fa-minus-square', this.action_quit_session); + }, + action_shorcode: function(e){ + return web_client.action_manager.do_action({ + type: 'ir.actions.act_window', + name : _t('Shortcode'), + res_model: 'im_chat.shortcode', + view_mode: 'tree,form', + view_type: 'tree', + views: [[false, 'list'], [false, 'form']], + target: "new", + limit: 80, + flags: { + action_buttons: true, + pager: true, + } + }); + }, + action_quit_session: function(e){ + var self = this; + var Session = new Model("im_chat.session"); + return Session.call("quit_user", [this.get("session").uuid]).then(function(res) { + if(! res){ + self.do_warn(_t("Warning"), _t("You are only 2 identified users. Just close the conversation to leave.")); + } + }); + }, + // session + session_update_state: function(state){ + var self = this; + var args = arguments; + var super_call = this._super; + // broadcast the state changing + return new Model("im_chat.session").call("update_state", [], {"uuid" : this.get("session").uuid, "state" : state}).then(function(){ + super_call.apply(self, args); + }); + }, + // window title + window_title_change: function() { + this.super(); + var title = undefined; + if (this.get("waiting_messages") !== 0) { + title = _.str.sprintf(_t("%d Messages"), this.get("waiting_messages")) + } + web_client.set_title_part("im_messages", title); + }, + // TODO : change this way + add_user: function(user){ + return new Model("im_chat.session").call("add_user", [this.get("session").uuid , user.id]); + }, +}); + + + +// ###### BACKEND : contact panel, top menu button ######### + +var UserWidget = Widget.extend({ + template: "im_chat.UserWidget", + events: { + "click": "activate_user", + }, + init: function(parent, user) { + this._super(parent); + this.set("id", user.id); + this.set("name", user.name); + this.set("im_status", user.im_status); + this.set("image_url", user.image_url); + }, + start: function() { + this.$el.data("user", {id:this.get("id"), name:this.get("name")}); + this.$el.draggable({helper: "clone"}); + this.on("change:im_status", this, this.update_status); + this.update_status(); + }, + update_status: function(){ + this.$(".oe_im_user_online").toggle(this.get('im_status') !== 'offline'); + var img_src = (this.get('im_status') == 'away' ? '/im_chat/static/src/img/yellow.png' : '/im_chat/static/src/img/green.png'); + this.$(".oe_im_user_online").attr('src', img_src); + }, + activate_user: function() { + this.trigger("user_clicked", this.get("id")); + }, +}); + +var InstantMessaging = Widget.extend({ + template: "im_chat.InstantMessaging", + events: { + "keydown .oe_im_searchbox": "input_change", + "keyup .oe_im_searchbox": "input_change", + "change .oe_im_searchbox": "input_change", + }, + init: function(parent) { + this._super(parent); + this.shown = false; + this.set("right_offset", 0); + this.set("current_search", ""); + this.users = []; + this.widgets = {}; + + // listen bus + this.bus = bus.bus; + this.bus.on("notification", this, this.on_notification); + }, + start: function() { + var self = this; + // ui + this.conv_manager = new im_chat_common.ConversationManager(this); + this.on("change:right_offset", this.conv_manager, _.bind(function() { + this.conv_manager.set("right_offset", this.get("right_offset")); + }, this)); + $(window).scroll(_.bind(this.position_compute, this)); + $(window).resize(_.bind(this.position_compute, this)); + this.$el.css("right", -this.$el.outerWidth()); + this.position_compute(); + + // business + this.on("change:current_search", this, this.user_search); + + // add a drag & drop listener + self.conv_manager.on("im_session_activated", self, function(conv) { + conv.$el.droppable({ + drop: function(event, ui) { + conv.add_user(ui.draggable.data("user")); + } + }); + }); + + // fetch the unread message and the recent activity (e.i. to re-init in case of refreshing page) + return session.rpc("/im_chat/init", {}).then(function(notifications) { + _.each(notifications, function(notif){ + self.conv_manager.on_notification(notif, {'load_history': true}); + }); + // start polling + self.bus.start_polling(); + }); + }, + on_notification: function(notification){ + var channel = notification[0]; + var message = notification[1]; + // user status notification + if(channel[1] === 'im_chat.presence'){ + if(message.im_status){ + this.user_update_status([message]); + } + } + }, + // ui + position_compute: function() { + var top = 48; + this.$el.css("top", top); + this.$el.css("bottom", 0); + }, + input_change: function() { + this.set("current_search", this.$(".oe_im_searchbox").val()); + }, + switch_display: function() { + this.position_compute(); + var fct = _.bind(function(place) { + this.set("right_offset", place + this.$el.outerWidth()); + this.$(".oe_im_searchbox").focus(); + }, this); + var opt = { + step: fct, + }; + if (this.shown) { + this.$el.animate({ + right: -this.$el.outerWidth(), + }, opt); + } else { + if (! bus.bus.activated) { + this.do_warn("Instant Messaging is not activated on this server. Try later.", ""); + return; + } + // update the list of user status when show the IM + this.user_search(); + this.$el.animate({ + right: 0, + }, opt); + } + this.shown = ! this.shown; + }, + // user methods + user_search: function(e) { + var self = this; + var user_model = new Model("res.users"); + return user_model.call('im_search', [this.get("current_search"), USERS_LIMIT]).then(function(result){ + self.$(".oe_im_input").val(""); + var old_widgets = self.widgets; + self.widgets = {}; + self.users = []; + _.each(result, function(user) { + user.image_url = session.url('/web/image', {model:'res.users', field: 'image_small', id: user.id}); + var widget = new UserWidget(self, user); + widget.appendTo(self.$(".oe_im_users")); + widget.on("user_clicked", self, self.user_clicked); + self.widgets[user.id] = widget; + self.users.push(user); + }); + _.each(old_widgets, function(w) { + w.destroy(); + }); + }); + }, + user_clicked: function(user_id) { + var self = this; + var sessions = new Model("im_chat.session"); + return sessions.call("session_get", [user_id]).then(function(session) { + self.conv_manager.session_apply(session, {'focus': true, 'force_open': true}); + }); + }, + user_update_status: function(users_list){ + var self = this; + _.each(users_list, function(el) { + if (self.widgets[el.id]) { + self.widgets[el.id].set("im_status", el.im_status); + } + }); + } +}); + + +var ImTopButton = Widget.extend({ + template:'im_chat.ImTopButton', + events: { + "click": "clicked", + }, + start: function() { + // Create the InstantMessaging widget and put it in the DOM + var im = new InstantMessaging(this); + web_client.im_messaging = im; + im.appendTo(web_client.$el); + // Bind the click action to the ImTopButton + this.on("clicked", im, im.switch_display); + return this._super(); + }, + clicked: function(ev) { + ev.preventDefault(); + this.trigger("clicked"); + }, +}); + +// Put the ImTopButton widget in the systray menu if the user is an employee +var Users = new Model('res.users'); +Users.call('has_group', ['base.group_user']).done(function(is_employee) { + if (is_employee) { + SystrayMenu.Items.push(ImTopButton); + } +}); + +return { + InstantMessaging: InstantMessaging, + UserWidget: UserWidget, +}; + +}); |
