summaryrefslogtreecommitdiff
path: root/addons/im/static/src/js/im.js
diff options
context:
space:
mode:
authorMartin Trigaux <mat@openerp.com>2013-09-11 13:07:55 +0200
committerMartin Trigaux <mat@openerp.com>2013-09-11 13:07:55 +0200
commitc48504fdba1ef68033c5e6c3b7929ea4e153d4b7 (patch)
tree471c4c37f5b76a4f034b5de805655d5fc5dcf867 /addons/im/static/src/js/im.js
parent9349ba848497b9c5b7ded809a4db6b1e3b26b6a6 (diff)
parent3fa90321e11d28df4e2b874ddfa450dc73e8e0af (diff)
[MERGE] sync with trunk (state -> stage removed some test)
bzr revid: mat@openerp.com-20130911110755-zf3ytf9m27im6x9k
Diffstat (limited to 'addons/im/static/src/js/im.js')
-rw-r--r--addons/im/static/src/js/im.js373
1 files changed, 40 insertions, 333 deletions
diff --git a/addons/im/static/src/js/im.js b/addons/im/static/src/js/im.js
index a271c9eccf0..6fbf452f974 100644
--- a/addons/im/static/src/js/im.js
+++ b/addons/im/static/src/js/im.js
@@ -1,17 +1,26 @@
-openerp.im = function(instance) {
+(function() {
+ "use strict";
+
+ var instance = openerp;
+
+ openerp.im = {};
var USERS_LIMIT = 20;
- var ERROR_DELAY = 5000;
- var _t = instance.web._t,
- _lt = instance.web._lt;
+ var _t = instance.web._t;
var QWeb = instance.web.qweb;
instance.web.UserMenu.include({
do_update: function(){
var self = this;
this.update_promise.then(function() {
+ im_common.notification = function(message) {
+ instance.client.do_warn(message);
+ };
+ // TODO: allow to use a different host for the chat
+ im_common.connection = new openerp.Session(self, null, {session_id: openerp.session.session_id});
+
var im = new instance.im.InstantMessaging(self);
im.appendTo(instance.client.$el);
var button = new instance.im.ImTopButton(this);
@@ -45,7 +54,8 @@ openerp.im = function(instance) {
this.set("right_offset", 0);
this.set("current_search", "");
this.users = [];
- this.c_manager = new instance.im.ConversationManager(this);
+ this.c_manager = new im_common.ConversationManager(this);
+ window.im_conversation_manager = this.c_manager;
this.on("change:right_offset", this.c_manager, _.bind(function() {
this.c_manager.set("right_offset", this.get("right_offset"));
}, this));
@@ -62,7 +72,15 @@ openerp.im = function(instance) {
var self = this;
- return this.c_manager.start_polling();
+ return this.c_manager.start_polling().then(function() {
+ self.c_manager.on("new_conversation", self, function(conv) {
+ conv.$el.droppable({
+ drop: function(event, ui) {
+ self.add_user(conv, ui.draggable.data("user"));
+ }
+ });
+ });
+ });
},
calc_box: function() {
var $topbar = instance.client.$(".oe_topbar");
@@ -77,17 +95,19 @@ openerp.im = function(instance) {
search_changed: function(e) {
var users = new instance.web.Model("im.user");
var self = this;
- return this.user_search_dm.add(users.call("search_users",
- [[["name", "ilike", this.get("current_search")], ["id", "<>", instance.session.uid]],
- ["name", "user", "uuid", "im_status"], USERS_LIMIT], {context:new instance.web.CompoundContext()})).then(function(result) {
- self.c_manager.add_to_user_cache(result);
+ return this.user_search_dm.add(users.call("search_users", [this.get("current_search"), ["name", "user_id", "uuid", "im_status"],
+ USERS_LIMIT], {context:new instance.web.CompoundContext()})).then(function(users) {
+ var logged_users = _.filter(users, function(u) { return !!u.im_status; });
+ var non_logged_users = _.filter(users, function(u) { return !u.im_status; });
+ users = logged_users.concat(non_logged_users);
+ self.c_manager.add_to_user_cache(users);
self.$(".oe_im_input").val("");
var old_users = self.users;
self.users = [];
- _.each(result, function(user) {
+ _.each(users, function(user) {
var widget = new instance.im.UserWidget(self, self.c_manager.get_user(user.id));
widget.appendTo(self.$(".oe_im_users"));
- widget.on("activate_user", self, self.activate_user);
+ widget.on("activate_user", self, function(user) {self.c_manager.chat_with_users([user]);});
self.users.push(widget);
});
_.each(old_users, function(user) {
@@ -117,8 +137,8 @@ openerp.im = function(instance) {
}
this.shown = ! this.shown;
},
- activate_user: function(user) {
- this.c_manager.activate_user(user, true);
+ add_user: function(conversation, user) {
+ conversation.add_user(user);
},
});
@@ -133,6 +153,8 @@ openerp.im = function(instance) {
this.user.add_watcher();
},
start: function() {
+ this.$el.data("user", this.user);
+ this.$el.draggable({helper: "clone"});
var change_status = function() {
this.$(".oe_im_user_online").toggle(this.user.get("im_status") === true);
};
@@ -148,323 +170,8 @@ openerp.im = function(instance) {
},
});
- instance.im.ImUser = instance.web.Class.extend(instance.web.PropertiesMixin, {
- init: function(parent, user_rec) {
- instance.web.PropertiesMixin.init.call(this, parent);
- user_rec.image_url = instance.session.url("/im/static/src/img/avatar/avatar.jpeg");
- if (user_rec.user)
- user_rec.image_url = instance.session.url('/web/binary/image', {model:'res.users', field: 'image_small', id: user_rec.user[0]});
- this.set(user_rec);
- this.set("watcher_count", 0);
- this.on("change:watcher_count", this, function() {
- if (this.get("watcher_count") === 0)
- this.destroy();
- });
- },
- destroy: function() {
- this.trigger("destroyed");
- instance.web.PropertiesMixin.destroy.call(this);
- },
- add_watcher: function() {
- this.set("watcher_count", this.get("watcher_count") + 1);
- },
- remove_watcher: function() {
- this.set("watcher_count", this.get("watcher_count") - 1);
- },
- });
-
- instance.im.ConversationManager = instance.web.Controller.extend({
- init: function(parent) {
- this._super(parent);
- this.set("right_offset", 0);
- this.conversations = [];
- this.users = {};
- this.on("change:right_offset", this, this.calc_positions);
- this.set("window_focus", true);
- this.set("waiting_messages", 0);
- this.focus_hdl = _.bind(function() {
- this.set("window_focus", true);
- }, this);
- $(window).bind("focus", this.focus_hdl);
- this.blur_hdl = _.bind(function() {
- this.set("window_focus", false);
- }, this);
- $(window).bind("blur", this.blur_hdl);
- this.on("change:window_focus", this, this.window_focus_change);
- this.window_focus_change();
- this.on("change:waiting_messages", this, this.messages_change);
- this.messages_change();
- this.create_ting();
- this.activated = false;
- this.users_cache = {};
- this.last = null;
- this.unload_event_handler = _.bind(this.unload, this);
- },
- start_polling: function() {
- var self = this;
- return new instance.web.Model("im.user").call("get_by_user_id", [instance.session.uid]).then(function(my_id) {
- self.my_id = my_id["id"];
- return self.ensure_users([self.my_id]).then(function() {
- var me = self.users_cache[self.my_id];
- delete self.users_cache[self.my_id];
- self.me = me;
- self.rpc("/longpolling/im/activated", {}, {shadow: true}).then(function(activated) {
- if (activated) {
- self.activated = true;
- $(window).on("unload", self.unload_event_handler);
- self.poll();
- }
- }, function(a, e) {
- e.preventDefault();
- });
- });
- });
- },
- unload: function() {
- return new instance.web.Model("im.user").call("im_disconnect", [], {context: new instance.web.CompoundContext()});
- },
- ensure_users: function(user_ids) {
- var no_cache = {};
- _.each(user_ids, function(el) {
- if (! this.users_cache[el])
- no_cache[el] = el;
- }, this);
- var self = this;
- if (_.size(no_cache) === 0)
- return $.when();
- else
- return new instance.web.Model("im.user").call("read", [_.values(no_cache), ["name", "user", "uuid", "im_status"]],
- {context: new instance.web.CompoundContext()}).then(function(users) {
- self.add_to_user_cache(users);
- });
- },
- add_to_user_cache: function(user_recs) {
- _.each(user_recs, function(user_rec) {
- if (! this.users_cache[user_rec.id]) {
- var user = new instance.im.ImUser(this, user_rec);
- this.users_cache[user_rec.id] = user;
- user.on("destroyed", this, function() {
- delete this.users_cache[user_rec.id];
- });
- }
- }, this);
- },
- get_user: function(user_id) {
- return this.users_cache[user_id];
- },
- poll: function() {
- var self = this;
- var user_ids = _.map(this.users_cache, function(el) {
- return el.get("id");
- });
- this.rpc("/longpolling/im/poll", {
- last: this.last,
- users_watch: user_ids,
- context: instance.web.pyeval.eval('context', {}),
- }, {shadow: true}).then(function(result) {
- _.each(result.users_status, function(el) {
- if (self.get_user(el.id))
- self.get_user(el.id).set(el);
- });
- self.last = result.last;
- var user_ids = _.pluck(_.pluck(result.res, "from_id"), 0);
- self.ensure_users(user_ids).then(function() {
- _.each(result.res, function(mes) {
- var user = self.get_user(mes.from_id[0]);
- self.received_message(mes, user);
- });
- self.poll();
- });
- }, function(unused, e) {
- e.preventDefault();
- setTimeout(_.bind(self.poll, self), ERROR_DELAY);
- });
- },
- get_activated: function() {
- return this.activated;
- },
- create_ting: function() {
- if (typeof(Audio) === "undefined") {
- this.ting = {play: function() {}};
- return;
- }
- var kitten = jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined;
- this.ting = new Audio(instance.webclient.session.origin + "/im/static/src/audio/" + (kitten ? "purr" : "Ting") +
- (new Audio().canPlayType("audio/ogg; codecs=vorbis") ? ".ogg" : ".mp3"));
- },
- window_focus_change: function() {
- if (this.get("window_focus")) {
- this.set("waiting_messages", 0);
- }
- },
- messages_change: function() {
- if (! instance.webclient.set_title_part)
- return;
- instance.webclient.set_title_part("aa_im_messages", this.get("waiting_messages") === 0 ? undefined :
- _.str.sprintf(_t("%d Messages"), this.get("waiting_messages")));
- },
- activate_user: function(user, focus) {
- var conv = this.users[user.get('id')];
- if (! conv) {
- conv = new instance.im.Conversation(this, user, this.me);
- conv.appendTo(instance.client.$el);
- conv.on("destroyed", this, function() {
- this.conversations = _.without(this.conversations, conv);
- delete this.users[conv.user.get('id')];
- this.calc_positions();
- });
- this.conversations.push(conv);
- this.users[user.get('id')] = conv;
- this.calc_positions();
- }
- if (focus)
- conv.focus();
- return conv;
- },
- received_message: function(message, user) {
- if (! this.get("window_focus")) {
- this.set("waiting_messages", this.get("waiting_messages") + 1);
- this.ting.play();
- this.create_ting();
- }
- var conv = this.activate_user(user);
- conv.received_message(message);
- },
- calc_positions: function() {
- var current = this.get("right_offset");
- _.each(_.range(this.conversations.length), function(i) {
- this.conversations[i].set("right_position", current);
- current += this.conversations[i].$el.outerWidth(true);
- }, this);
- },
- destroy: function() {
- $(window).off("unload", this.unload_event_handler);
- $(window).unbind("blur", this.blur_hdl);
- $(window).unbind("focus", this.focus_hdl);
- this._super();
- },
- });
-
- instance.im.Conversation = instance.web.Widget.extend({
- "template": "Conversation",
- events: {
- "keydown input": "send_message",
- "click .oe_im_chatview_close": "destroy",
- "click .oe_im_chatview_header": "show_hide",
- },
- init: function(parent, user, me) {
- this._super(parent);
- this.me = me;
- this.user = user;
- this.user.add_watcher();
- this.set("right_position", 0);
- this.shown = true;
- this.set("pending", 0);
- },
- start: function() {
- var change_status = function() {
- this.$el.toggleClass("oe_im_chatview_disconnected_status", this.user.get("im_status") === false);
- this.$(".oe_im_chatview_online").toggle(this.user.get("im_status") === true);
- this._go_bottom();
- };
- this.user.on("change:im_status", this, change_status);
- change_status.call(this);
-
- this.on("change:right_position", this, this.calc_pos);
- this.full_height = this.$el.height();
- this.calc_pos();
- this.on("change:pending", this, _.bind(function() {
- if (this.get("pending") === 0) {
- this.$(".oe_im_chatview_nbr_messages").text("");
- } else {
- this.$(".oe_im_chatview_nbr_messages").text("(" + this.get("pending") + ")");
- }
- }, this));
- },
- show_hide: function() {
- if (this.shown) {
- this.$el.animate({
- height: this.$(".oe_im_chatview_header").outerHeight(),
- });
- } else {
- this.$el.animate({
- height: this.full_height,
- });
- }
- this.shown = ! this.shown;
- if (this.shown) {
- this.set("pending", 0);
- }
- },
- calc_pos: function() {
- this.$el.css("right", this.get("right_position"));
- },
- received_message: function(message) {
- if (this.shown) {
- this.set("pending", 0);
- } else {
- this.set("pending", this.get("pending") + 1);
- }
- this._add_bubble(this.user, message.message, message.date);
- },
- send_message: function(e) {
- if(e && e.which !== 13) {
- return;
- }
- var mes = this.$("input").val();
- if (! mes.trim()) {
- return;
- }
- this.$("input").val("");
- var send_it = _.bind(function() {
- var model = new instance.web.Model("im.message");
- return model.call("post", [mes, this.user.get('id')],
- {context: new instance.web.CompoundContext()});
- }, this);
- var tries = 0;
- send_it().then(_.bind(function() {
- this._add_bubble(this.me, mes, instance.web.datetime_to_str(new Date()));
- }, this), function(error, e) {
- e.preventDefault();
- tries += 1;
- if (tries < 3)
- return send_it();
- });
- },
- _add_bubble: function(user, item, date) {
- var items = [item];
- if (user === this.last_user) {
- this.last_bubble.remove();
- items = this.last_items.concat(items);
- }
- this.last_user = user;
- this.last_items = items;
- date = instance.web.str_to_datetime(date);
- var now = new Date();
- var diff = now - date;
- if (diff > (1000 * 60 * 60 * 24)) {
- date = $.timeago(date);
- } else {
- date = date.toString(Date.CultureInfo.formatPatterns.shortTime);
- }
-
- this.last_bubble = $(QWeb.render("Conversation.bubble", {"items": items, "user": user, "time": date}));
- $(this.$(".oe_im_chatview_content").children()[0]).append(this.last_bubble);
- this._go_bottom();
- },
- _go_bottom: function() {
- this.$(".oe_im_chatview_content").scrollTop($(this.$(".oe_im_chatview_content").children()[0]).height());
- },
- focus: function() {
- this.$(".oe_im_chatview_input").focus();
- if (! this.shown)
- this.show_hide();
- },
- destroy: function() {
- this.user.remove_watcher();
- this.trigger("destroyed");
- return this._super();
- },
- });
+ im_common.technical_messages_handlers.force_kitten = function() {
+ openerp.webclient.to_kitten();
+ };
-} \ No newline at end of file
+})(); \ No newline at end of file