[FIX] bus, im_chat, im_livechat : use correct session to rpc call, little refactoring of im_livechat js, and prepare js code for Odoo Support.
This commit is contained in:
parent
130873f0f6
commit
1b9c404e49
|
@ -10,19 +10,28 @@
|
|||
this.activated = false;
|
||||
this.channels = [];
|
||||
this.last = 0;
|
||||
this.stop = false;
|
||||
},
|
||||
start_polling: function(){
|
||||
if(!this.activated){
|
||||
this.poll();
|
||||
setTimeout(this.poll(), 1);
|
||||
this.stop = false;
|
||||
}
|
||||
},
|
||||
stop_polling: function(){
|
||||
this.activated = false;
|
||||
this.stop = true;
|
||||
this.channels = [];
|
||||
},
|
||||
poll: function() {
|
||||
var self = this;
|
||||
self.activated = true;
|
||||
var data = {'channels': self.channels, 'last': self.last, 'options' : self.options};
|
||||
openerp.jsonRpc('/longpolling/poll', 'call', data).then(function(result) {
|
||||
openerp.session.rpc('/longpolling/poll', data, {shadow : true}).then(function(result) {
|
||||
_.each(result, _.bind(self.on_notification, self));
|
||||
self.poll();
|
||||
if(!self.stop){
|
||||
self.poll();
|
||||
}
|
||||
}, function(unused, e) {
|
||||
// random delay to avoid massive longpolling
|
||||
setTimeout(_.bind(self.poll, self), bus.ERROR_DELAY + (Math.floor((Math.random()*20)+1)*1000));
|
||||
|
|
|
@ -52,6 +52,12 @@ class im_chat_session(osv.Model):
|
|||
'uuid': lambda *args: '%s' % uuid.uuid4(),
|
||||
}
|
||||
|
||||
def is_in_session(self, cr, uid, uuid, user_id, context=None):
|
||||
""" return if the given user_id is in the session """
|
||||
sids = self.search(cr, uid, [('uuid', '=', uuid)], context=context, limit=1)
|
||||
for session in self.browse(cr, uid, sids, context=context):
|
||||
return user_id and user_id in [u.id for u in session.user_ids]
|
||||
|
||||
def users_infos(self, cr, uid, ids, context=None):
|
||||
""" get the user infos for all the user in the session """
|
||||
for session in self.pool["im_chat.session"].browse(cr, uid, ids, context=context):
|
||||
|
@ -220,6 +226,17 @@ class im_chat_message(osv.Model):
|
|||
self.pool['bus.bus'].sendmany(cr, uid, notifications)
|
||||
return message_id
|
||||
|
||||
def get_messages(self, cr, uid, uuid, last_id=False, limit=20, context=None):
|
||||
""" get messages (id desc) from given last_id in the given session """
|
||||
Session = self.pool['im_chat.session']
|
||||
if Session.is_in_session(cr, uid, uuid, uid, context=context):
|
||||
domain = [("to_id.uuid", "=", uuid)]
|
||||
if last_id:
|
||||
domain.append(("id", "<", last_id));
|
||||
return self.search_read(cr, uid, domain, ['id', 'create_date','to_id','from_id', 'type', 'message'], limit=limit, context=context)
|
||||
return False
|
||||
|
||||
|
||||
class im_chat_presence(osv.Model):
|
||||
""" im_chat_presence status can be: online, away or offline.
|
||||
This model is a one2one, but is not attached to res_users to avoid database concurrence errors
|
||||
|
@ -400,4 +417,9 @@ class Controller(openerp.addons.bus.bus.Controller):
|
|||
headers.append(('Content-Length', len(image_data)))
|
||||
return request.make_response(image_data, headers)
|
||||
|
||||
@openerp.http.route(['/im_chat/history'], type="json", auth="none")
|
||||
def history(self, uuid, last_id=False, limit=20):
|
||||
registry, cr, uid, context = request.registry, request.cr, request.session.uid, request.context
|
||||
return registry["im_chat.message"].get_messages(cr, openerp.SUPERUSER_ID, uuid, last_id, limit, context=context)
|
||||
|
||||
# vim:et:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(function(){
|
||||
|
||||
"use strict";
|
||||
|
||||
var _t = openerp._t;
|
||||
var _lt = openerp._lt;
|
||||
var QWeb = openerp.qweb;
|
||||
|
@ -99,10 +100,7 @@
|
|||
if(session.state !== 'closed'){
|
||||
conv = new im_chat.Conversation(this, this, session, this.options);
|
||||
conv.appendTo($("body"));
|
||||
conv.on("destroyed", this, function() {
|
||||
delete this.sessions[session.uuid];
|
||||
this.calc_positions();
|
||||
});
|
||||
conv.on("destroyed", this, _.bind(this.delete_session, this));
|
||||
this.sessions[session.uuid] = conv;
|
||||
this.calc_positions();
|
||||
}
|
||||
|
@ -124,6 +122,10 @@
|
|||
}
|
||||
return conv;
|
||||
},
|
||||
delete_session: function(uuid){
|
||||
delete this.sessions[uuid];
|
||||
this.calc_positions();
|
||||
},
|
||||
received_message: function(message) {
|
||||
var self = this;
|
||||
var session_id = message.to_id[0];
|
||||
|
@ -250,12 +252,17 @@
|
|||
load_history: function(){
|
||||
var self = this;
|
||||
if(this.loading_history){
|
||||
var domain = [["to_id.uuid", "=", this.get("session").uuid]];
|
||||
_.first(this.get("messages")) && domain.push(['id','<', _.first(this.get("messages")).id]);
|
||||
new openerp.Model("im_chat.message").call("search_read", [domain, ['id', 'create_date','to_id','from_id', 'type', 'message'], 0, NBR_LIMIT_HISTORY]).then(function(messages){
|
||||
self.insert_messages(messages);
|
||||
if(messages.length != NBR_LIMIT_HISTORY){
|
||||
self.loading_history = false;
|
||||
var data = {uuid: self.get("session").uuid, limit: NBR_LIMIT_HISTORY};
|
||||
var lastid = _.first(this.get("messages")) ? _.first(this.get("messages")).id : false;
|
||||
if(lastid){
|
||||
data["last_id"] = lastid;
|
||||
}
|
||||
openerp.session.rpc("/im_chat/history", data).then(function(messages){
|
||||
if(messages){
|
||||
self.insert_messages(messages);
|
||||
if(messages.length != NBR_LIMIT_HISTORY){
|
||||
self.loading_history = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -410,7 +417,7 @@
|
|||
this.update_fold_state('closed');
|
||||
},
|
||||
destroy: function() {
|
||||
this.trigger("destroyed");
|
||||
this.trigger("destroyed", this.get('session').uuid);
|
||||
return this._super();
|
||||
}
|
||||
});
|
||||
|
@ -436,7 +443,7 @@
|
|||
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', openerp.session.server + img_src);
|
||||
this.$(".oe_im_user_online").attr('src', img_src);
|
||||
},
|
||||
activate_user: function() {
|
||||
this.trigger("activate_user", this.get("id"));
|
||||
|
@ -556,7 +563,7 @@
|
|||
var self = this;
|
||||
var sessions = new openerp.web.Model("im_chat.session");
|
||||
return sessions.call("session_get", [user_id]).then(function(session) {
|
||||
self.c_manager.activate_session(session, true);
|
||||
self.c_manager.activate_session(session, true);
|
||||
});
|
||||
},
|
||||
update_users_status: function(users_list){
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
<img t-att-src="widget.get('image_url')" class="oe_im_user_avatar"/>
|
||||
</span>
|
||||
<span class="oe_im_user_name"><t t-esc="widget.get('name')"/></span>
|
||||
<img t-att-src="_s +'/im_chat/static/src/img/green.png'" t-att-data-im-user-id="widget.get('id')" class="oe_im_user_online"/>
|
||||
<img t-att-src="'/im_chat/static/src/img/green.png'" t-att-data-im-user-id="widget.get('id')" class="oe_im_user_online"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="im_chat.InstantMessaging">
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
import random
|
||||
import openerp
|
||||
import json
|
||||
import openerp.addons.im_chat.im_chat
|
||||
|
||||
from openerp.osv import osv, fields
|
||||
|
@ -193,6 +194,15 @@ class im_chat_session(osv.Model):
|
|||
'fullname' : fields.function(_get_fullname, type="char", string="Complete name"),
|
||||
}
|
||||
|
||||
def is_in_session(self, cr, uid, uuid, user_id, context=None):
|
||||
""" return if the given user_id is in the session """
|
||||
sids = self.search(cr, uid, [('uuid', '=', uuid)], context=context, limit=1)
|
||||
for session in self.browse(cr, uid, sids, context=context):
|
||||
if session.anonymous_name and not user_id:
|
||||
return True
|
||||
else:
|
||||
return super(im_chat_session, self).is_in_session(cr, uid, uuid, user_id, context=context)
|
||||
|
||||
def users_infos(self, cr, uid, ids, context=None):
|
||||
""" add the anonymous user in the user of the session """
|
||||
for session in self.browse(cr, uid, ids, context=context):
|
||||
|
@ -237,3 +247,4 @@ class LiveChatController(http.Controller):
|
|||
reg = openerp.modules.registry.RegistryManager.get(db)
|
||||
with reg.cursor() as cr:
|
||||
return len(reg.get('im_livechat.channel').get_available_users(cr, uid, channel)) > 0
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
"use strict";
|
||||
|
||||
var _t = openerp._t;
|
||||
|
||||
var im_livechat = {};
|
||||
openerp.im_livechat = im_livechat;
|
||||
im_livechat.COOKIE_NAME = 'livechat_conversation';
|
||||
|
||||
/*
|
||||
The state of anonymous session is hold by the client and not the server.
|
||||
|
@ -19,7 +19,7 @@
|
|||
init: function(){
|
||||
this._super.apply(this, arguments);
|
||||
this.shown = true;
|
||||
this.loading_history = false; // unactivate the loading history
|
||||
this.loading_history = true; // since the session is kept after a refresh, anonymous can reload their history
|
||||
},
|
||||
show: function(){
|
||||
this._super.apply(this, arguments);
|
||||
|
@ -48,40 +48,78 @@
|
|||
var session = this.get('session');
|
||||
session.state = state;
|
||||
this.set('session', session);
|
||||
openerp.set_cookie(im_livechat.COOKIE_NAME, JSON.stringify(session), 60*60);
|
||||
},
|
||||
click_close: function(e) {
|
||||
this._super(e);
|
||||
openerp.set_cookie(im_livechat.COOKIE_NAME, "", -1);
|
||||
},
|
||||
});
|
||||
|
||||
// To avoid exeption when the anonymous has close his
|
||||
// conversation and when operator send him a message.
|
||||
openerp.im_chat.ConversationManager.include({
|
||||
received_message: function(message) {
|
||||
try{
|
||||
this._super(message);
|
||||
}catch(e){}
|
||||
}
|
||||
});
|
||||
|
||||
// TODO move this to openerpframework.js, ask xmo
|
||||
openerp.set_cookie = function(name, value, ttl) {
|
||||
ttl = ttl || 24*60*60*365;
|
||||
document.cookie = [
|
||||
name + '=' + value,
|
||||
'path=/',
|
||||
'max-age=' + ttl,
|
||||
'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
|
||||
].join(';');
|
||||
};
|
||||
|
||||
im_livechat.LiveSupport = openerp.Widget.extend({
|
||||
init: function(server_url, db, channel, options) {
|
||||
var self = this;
|
||||
options = options || {};
|
||||
_.defaults(options, {
|
||||
buttonText: _t("Chat with one of our collaborators"),
|
||||
inputPlaceholder: null,
|
||||
defaultMessage: _t("How may I help you?"),
|
||||
defaultUsername: _t("Anonymous"),
|
||||
defaultUsername: _t("Visitor"),
|
||||
});
|
||||
openerp.session = new openerp.Session();
|
||||
|
||||
openerp.session = new openerp.Session(null, server_url, { use_cors: false });
|
||||
// load the qweb templates
|
||||
var defs = [];
|
||||
var templates = ['/im_livechat/static/src/xml/im_livechat.xml','/im_chat/static/src/xml/im_chat.xml'];
|
||||
var templates = ['/im_livechat/static/src/xml/im_livechat.xml', '/im_chat/static/src/xml/im_chat.xml'];
|
||||
_.each(templates, function(tmpl){
|
||||
defs.push(openerp.session.rpc('/web/proxy/load', {path: tmpl}).then(function(xml) {
|
||||
openerp.qweb.add_template(xml);
|
||||
}));
|
||||
});
|
||||
return $.when.apply($, defs).then(function() {
|
||||
return openerp.session.rpc("/im_livechat/available", {db: db, channel: channel}).then(function(activated) {
|
||||
if(activated){
|
||||
var button = new im_livechat.ChatButton(null, channel, options);
|
||||
button.appendTo($("body"));
|
||||
if (options.auto){
|
||||
button.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
self.setup(db, channel, options);
|
||||
});
|
||||
},
|
||||
setup: function(db, channel, options){
|
||||
var self = this;
|
||||
var session = openerp.get_cookie(im_livechat.COOKIE_NAME);
|
||||
if(session){
|
||||
self.build_button(channel, options, JSON.parse(session));
|
||||
}else{
|
||||
openerp.session.rpc("/im_livechat/available", {db: db, channel: channel}).then(function(activated) {
|
||||
if(activated){
|
||||
self.build_button(channel, options);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
build_button: function(channel, options, session){
|
||||
var button = new im_livechat.ChatButton(null, channel, options, session);
|
||||
button.appendTo($("body"));
|
||||
if (options.auto){
|
||||
button.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
im_livechat.ChatButton = openerp.Widget.extend({
|
||||
|
@ -89,56 +127,79 @@
|
|||
events: {
|
||||
"click": "click"
|
||||
},
|
||||
init: function(parent, channel, options) {
|
||||
init: function(parent, channel, options, session) {
|
||||
this._super(parent);
|
||||
this.channel = channel;
|
||||
this.options = options;
|
||||
this.text = options.buttonText;
|
||||
this.session = session || false;
|
||||
this.conv = false;
|
||||
this.no_session_message = _t("None of our collaborators seems to be available, please try again later.");
|
||||
},
|
||||
start: function() {
|
||||
this.$().append(openerp.qweb.render("chatButton", {widget: this}));
|
||||
// set up the manager
|
||||
this.manager = new openerp.im_chat.ConversationManager(this, this.options);
|
||||
this.manager.set("bottom_offset", $('.oe_chat_button').outerHeight());
|
||||
this.manager.notification = function(notif){ // override the notification default function
|
||||
alert(notif);
|
||||
}
|
||||
if(this.session){
|
||||
this.set_conversation(this.session);
|
||||
}
|
||||
},
|
||||
click: function() {
|
||||
if (! this.manager) {
|
||||
this.manager = new openerp.im_chat.ConversationManager(this, this.options);
|
||||
this.manager.set("bottom_offset", $('.oe_chat_button').outerHeight()); // TODO correct the value (no hardcode damned !)
|
||||
// override the notification default function
|
||||
this.manager.notification = function(notif){
|
||||
alert(notif);
|
||||
var self = this;
|
||||
if (!this.conv){
|
||||
openerp.session.rpc("/im_livechat/get_session", {"channel_id" : self.channel, "anonymous_name" : this.options["defaultUsername"]}, {shadow: true}).then(function(session) {
|
||||
if (! session) {
|
||||
self.manager.notification(self.no_session_message);
|
||||
return;
|
||||
}
|
||||
session.state = 'open';
|
||||
// save the session in a cookie
|
||||
openerp.set_cookie(im_livechat.COOKIE_NAME, JSON.stringify(session), 60*60);
|
||||
// create the conversation with the received session
|
||||
self.set_conversation(session, true);
|
||||
});
|
||||
}
|
||||
},
|
||||
set_conversation: function(session, welcome_message){
|
||||
var self = this;
|
||||
this.session = session;
|
||||
if(session.state === 'closed'){
|
||||
return;
|
||||
}
|
||||
this.conv = this.manager.apply_session(session);
|
||||
this.conv.on("destroyed", this, function() {
|
||||
openerp.bus.bus.stop_polling();
|
||||
delete self.conv;
|
||||
delete self.session;
|
||||
});
|
||||
// start the polling
|
||||
openerp.bus.bus.add_channel(session.uuid);
|
||||
openerp.bus.bus.start_polling();
|
||||
// add the automatic welcome message
|
||||
if(welcome_message){
|
||||
this.send_welcome_message();
|
||||
}
|
||||
},
|
||||
send_welcome_message: function(){
|
||||
var self = this;
|
||||
if(this.session.users.length > 0){
|
||||
if (self.options.defaultMessage) {
|
||||
setTimeout(function(){
|
||||
self.conv.received_message({
|
||||
id : 1,
|
||||
type: "message",
|
||||
message: self.options.defaultMessage,
|
||||
create_date: openerp.datetime_to_str(new Date()),
|
||||
from_id: [self.session.users[0].id, self.session.users[0].name],
|
||||
to_id: [0, self.session.uuid]
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
return this.chat();
|
||||
},
|
||||
chat: function() {
|
||||
var self = this;
|
||||
if (_.keys(this.manager.sessions).length > 0)
|
||||
return;
|
||||
|
||||
openerp.session.rpc("/im_livechat/get_session", {"channel_id" : self.channel, "anonymous_name" : this.options["defaultUsername"]}, {shadow: true}).then(function(session) {
|
||||
if (! session) {
|
||||
self.manager.notification(_t("None of our collaborators seems to be available, please try again later."));
|
||||
return;
|
||||
}
|
||||
var conv = self.manager.activate_session(session, [], true);
|
||||
// start the polling
|
||||
openerp.bus.bus.add_channel(session.uuid);
|
||||
openerp.bus.bus.start_polling();
|
||||
// add the automatic welcome message
|
||||
if(session.users.length > 0){
|
||||
if (self.options.defaultMessage) {
|
||||
setTimeout(function(){
|
||||
conv.received_message({
|
||||
id : 1,
|
||||
type: "message",
|
||||
message: self.options.defaultMessage,
|
||||
create_date: openerp.datetime_to_str(new Date()),
|
||||
from_id: [session.users[0].id, session.users[0].name],
|
||||
to_id: [0, session.uuid]
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue