From 1029571c35bf5372318590a439e53e3a881b2308 Mon Sep 17 00:00:00 2001
From: Aaron Bohy <aab@odoo.com>
Date: Mon, 14 Dec 2015 14:31:04 +0100
Subject: [PATCH] [FIX] im_livechat: various fixes

- Don't display livechat button if no operator available
- Livechat windows persistence through website pages
- Auto popup feature re-introduced (inadvertently removed at rev. f23f57cc)
- Operators that are 'away' are available, as 'away' means that the focus isn't
  on the Odoo tab for at least 10 minutes, but the user is still connected.
- Avoid duplicated messages when the visitor is a connected user
- Unfold livechat window on first 'close' click as the event is intercepted to
  ask the user feedback before actually closing the window
---
 addons/im_livechat/controllers/main.py        |  8 +++
 .../im_livechat/models/im_livechat_channel.py |  2 +-
 .../im_livechat/static/src/js/im_livechat.js  | 70 +++++++++++++++----
 3 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/addons/im_livechat/controllers/main.py b/addons/im_livechat/controllers/main.py
index 2fe7b2070ae1..4b1f5775da95 100644
--- a/addons/im_livechat/controllers/main.py
+++ b/addons/im_livechat/controllers/main.py
@@ -32,6 +32,10 @@ class LivechatController(http.Controller):
         info = request.env['im_livechat.channel'].match_rules(request, channel.id, username=username)
         return request.render('im_livechat.loader', {'info': info, 'web_session_required': True}) if info else False
 
+    @http.route('/im_livechat/available', type='json', auth="public")
+    def available(self, channel_id):
+        return len(request.env['im_livechat.channel'].browse(channel_id).get_available_users())
+
     @http.route('/im_livechat/get_session', type="json", auth='public')
     def get_session(self, channel_id, anonymous_name, **kwargs):
         # if geoip, add the country name to the anonymous name
@@ -42,6 +46,10 @@ class LivechatController(http.Controller):
             anonymous_name = request.env.user.name
         return request.env["im_livechat.channel"].get_mail_channel(channel_id, anonymous_name)
 
+    @http.route('/im_livechat/history', type="json", auth="public")
+    def history(self, channel_id, limit):
+        return request.env["mail.channel"].browse(channel_id).channel_fetch_message(limit=limit)
+
     @http.route('/im_livechat/feedback', type='json', auth='public')
     def feedback(self, uuid, rate, reason=None, **kwargs):
         Channel = request.env['mail.channel']
diff --git a/addons/im_livechat/models/im_livechat_channel.py b/addons/im_livechat/models/im_livechat_channel.py
index b4e213685864..a308fde4c092 100644
--- a/addons/im_livechat/models/im_livechat_channel.py
+++ b/addons/im_livechat/models/im_livechat_channel.py
@@ -144,7 +144,7 @@ class ImLivechatChannel(models.Model):
             :retuns : return the res.users having their im_status online
         """
         self.ensure_one()
-        return self.sudo().user_ids.filtered(lambda user: user.im_status == 'online')
+        return self.sudo().user_ids.filtered(lambda user: user.im_status == 'online' or user.im_status == 'away')
 
     @api.model
     def get_mail_channel(self, livechat_channel_id, anonymous_name):
diff --git a/addons/im_livechat/static/src/js/im_livechat.js b/addons/im_livechat/static/src/js/im_livechat.js
index fb957681276b..4179149d68bb 100644
--- a/addons/im_livechat/static/src/js/im_livechat.js
+++ b/addons/im_livechat/static/src/js/im_livechat.js
@@ -27,6 +27,8 @@ var LivechatButton = Widget.extend({
             default_username: _t("Visitor"),
             button_text: _t("Chat with one of our collaborators"),
             default_message: _t("How may I help you?"),
+            auto_popup: true,
+            auto_popup_timer: 10,  // auto popup after 10 seconds
         });
         this.channel = null;
         this.chat_window = null;
@@ -34,18 +36,48 @@ var LivechatButton = Widget.extend({
     },
 
     willStart: function () {
-        return this.load_qweb_template();
+        var self = this;
+        var cookie = utils.get_cookie('im_livechat_session');
+        var ready;
+        if (!cookie) {
+            ready = session.rpc("/im_livechat/available", {channel_id: this.options.channel_id});
+        } else {
+            var channel = JSON.parse(cookie);
+            ready = $.when(true, session.rpc("/im_livechat/history", {channel_id: channel.id, limit: 100}));
+        }
+        return ready.then(function (available, history) {
+            self.available = available;
+            self.history = history;
+            if (available) {
+                return self.load_qweb_template();
+            }
+        });
     },
 
     start: function () {
-        this.$el.text(this.options.button_text);
-        bus.on('notification', this, function (notification) {
-            this.add_message(notification[1]);
-            this.render_messages();
-            if (this.chat_window.folded) {
-                this.chat_window.update_unread(this.chat_window.unread_msgs+1);
+        if (!this.available) {
+            this.do_hide();
+        } else {
+            this.$el.text(this.options.button_text);
+            if (this.history) {
+                _.each(this.history.reverse(), this.add_message.bind(this));
+                this.open_chat();
+            } else if (this.options.auto_popup) {
+                var auto_popup_cookie = utils.get_cookie('im_livechat_auto_popup');
+                if (!auto_popup_cookie || JSON.parse(auto_popup_cookie)){
+                    setTimeout(this.open_chat.bind(this), this.options.auto_popup_timer*1000);
+                }
             }
-        });
+            bus.on('notification', this, function (notification) {
+                if (this.channel && (notification[0] === this.channel.uuid)) {
+                    this.add_message(notification[1]);
+                    this.render_messages();
+                    if (this.chat_window.folded) {
+                        this.chat_window.update_unread(this.chat_window.unread_msgs+1);
+                    }
+                }
+            });
+        }
         return this._super();
     },
 
@@ -87,6 +119,7 @@ var LivechatButton = Widget.extend({
                 bus.start_polling();
 
                 utils.set_cookie('im_livechat_session', JSON.stringify(channel), 60*60);
+                utils.set_cookie('im_livechat_auto_popup', JSON.stringify(false), 60*60);
             }
         });
     },
@@ -96,14 +129,16 @@ var LivechatButton = Widget.extend({
         var options = {
             display_stars: false,
         };
-        this.chat_window = new ChatWindow(this, channel.id, channel.name, false, channel.message_unread_counter, options);
+        var is_folded = (channel.state === 'folded');
+        this.chat_window = new ChatWindow(this, channel.id, channel.name, is_folded, channel.message_unread_counter, options);
         this.chat_window.appendTo($('body')).then(function () {
             self.chat_window.$el.css({right: 0, bottom: 0});
             self.$el.hide();
         });
         this.chat_window.on("close_chat_session", this, function () {
-            var input_disabled = this.chat_window.$(".o_chat_input input").prop('disabled')
+            var input_disabled = this.chat_window.$(".o_chat_input input").prop('disabled');
             if (this.messages.length > 1 && !input_disabled) {
+                this.chat_window.toggle_fold(false);
                 this.ask_feedback();
             } else {
                 this.close_chat();
@@ -114,7 +149,10 @@ var LivechatButton = Widget.extend({
                 e.preventDefault();
                 return self.send_message(message); // try again just in case
             });
-
+        });
+        this.chat_window.on("fold_channel", this, function () {
+            this.channel.state = (this.channel.state === 'open') ? 'folded' : 'open';
+            utils.set_cookie('im_livechat_session', JSON.stringify(this.channel), 60*60);
         });
     },
 
@@ -127,7 +165,7 @@ var LivechatButton = Widget.extend({
         return session.rpc("/mail/chat_post", {uuid: this.channel.uuid, message_content: message.content});
     },
 
-    add_message: function (data) {
+    add_message: function (data, options) {
         var msg = {
             id: data.id,
             attachment_ids: data.attachment_ids,
@@ -149,7 +187,11 @@ var LivechatButton = Widget.extend({
             msg.avatar_src = "/mail/static/src/img/smiley/avatar.jpg";
         }
 
-        this.messages.push(msg);
+        if (options && options.prepend) {
+            this.messages.unshift(msg);
+        } else {
+            this.messages.push(msg);
+        }
     },
 
     render_messages: function () {
@@ -166,7 +208,7 @@ var LivechatButton = Widget.extend({
             channel_ids: [this.channel.id],
             date: time.datetime_to_str(new Date()),
             tracking_value_ids: [],
-        });
+        }, {prepend: true});
     },
 
     ask_feedback: function () {
-- 
GitLab