From 67e901d3d0dea778e054dc8145f64f469909be70 Mon Sep 17 00:00:00 2001
From: Dmitriy Simushev <simushevds@ossg.ru>
Date: Wed, 6 Feb 2013 15:22:17 +0000
Subject: [PATCH] Call updateMessages function not from server but from chat
 window

---
 src/messenger/webim/js/compiled/chat/app.js   | 11 +--
 .../js/compiled/chat/collections/messages.js  |  5 +-
 src/messenger/webim/js/compiled/chat_app.js   | 16 ++---
 src/messenger/webim/js/source/chat/app.js     | 52 +++++++++++++-
 .../js/source/chat/collections/messages.js    | 50 +++----------
 .../webim/libs/classes/thread_processor.php   | 72 +++++++++----------
 6 files changed, 111 insertions(+), 95 deletions(-)

diff --git a/src/messenger/webim/js/compiled/chat/app.js b/src/messenger/webim/js/compiled/chat/app.js
index 8fbf96cd..44d2d646 100644
--- a/src/messenger/webim/js/compiled/chat/app.js
+++ b/src/messenger/webim/js/compiled/chat/app.js
@@ -5,8 +5,9 @@
  Copyright (c) 2005-2011 Mibew Messenger Community
  License: http://mibew.org/license.php
 */
-(function(a,j,k){var f=new j.Marionette.Application;f.addRegions({controlsRegion:"#controls-region",avatarRegion:"#avatar-region",messagesRegion:a.Regions.Messages,statusRegion:"#status-region",messageFormRegion:"#message-form-region",soundRegion:"#sound-region"});f.addInitializer(function(d){var g=a.Objects,c=a.Objects.Models,b=a.Objects.Models.Controls,h=a.Objects.Models.Status;g.server=new a.Server(k.extend({interactionType:MibewAPIChatInteraction},d.server));c.thread=new a.Models.Thread(d.thread);
-c.user=new a.Models.ChatUser(d.user);c.page=new a.Models.Page(d.page);var e=new a.Collections.Controls;c.user.get("isAgent")||(b.userName=new a.Models.UserNameControl({weight:220}),e.add(b.userName),b.sendMail=new a.Models.SendMailControl({weight:200,link:d.links.mailLink}),e.add(b.sendMail));c.user.get("isAgent")&&(b.redirect=new a.Models.RedirectControl({weight:200,link:d.links.redirectLink}),e.add(b.redirect),b.history=new a.Models.HistoryControl({weight:180,link:d.links.historyLink}),e.add(b.history));
-b.sound=new a.Models.SoundControl({weight:160});e.add(b.sound);b.refresh=new a.Models.RefreshControl({weight:140});e.add(b.refresh);d.links.sslLink&&(b.secureMode=new a.Models.SecureModeControl({weight:120,link:d.links.sslLink}),e.add(b.secureMode));b.close=new a.Models.CloseControl({weight:100});e.add(b.close);g.Collections.controls=e;f.controlsRegion.show(new a.Views.ControlsCollection({collection:e}));h.message=new a.Models.StatusMessage({hideTimeout:5E3});h.typing=new a.Models.StatusTyping({hideTimeout:5E3});
-g.Collections.status=new a.Collections.Status([h.message,h.typing]);f.statusRegion.show(new a.Views.StatusCollection({collection:g.Collections.status}));c.user.get("isAgent")||(c.avatar=new a.Models.Avatar,f.avatarRegion.show(new a.Views.Avatar({model:c.avatar})));g.Collections.messages=new a.Collections.Messages;c.messageForm=new a.Models.MessageForm(d.messageForm);f.messageFormRegion.show(new a.Views.MessageForm({model:c.messageForm}));f.messagesRegion.show(new a.Views.MessagesCollection({collection:g.Collections.messages}));
-c.sound=new a.Models.Sound;f.soundRegion.show(new a.Views.Sound({model:c.sound}));g.server.runUpdater()});a.Application=f})(Mibew,Backbone,_);
+(function(a,j,k){var d=new j.Marionette.Application;d.addRegions({controlsRegion:"#controls-region",avatarRegion:"#avatar-region",messagesRegion:a.Regions.Messages,statusRegion:"#status-region",messageFormRegion:"#message-form-region",soundRegion:"#sound-region"});d.addInitializer(function(e){var g=a.Objects,c=a.Objects.Models,b=a.Objects.Models.Controls,h=a.Objects.Models.Status;g.server=new a.Server(k.extend({interactionType:MibewAPIChatInteraction},e.server));c.thread=new a.Models.Thread(e.thread);
+c.user=new a.Models.ChatUser(e.user);c.page=new a.Models.Page(e.page);var f=new a.Collections.Controls;c.user.get("isAgent")||(b.userName=new a.Models.UserNameControl({weight:220}),f.add(b.userName),b.sendMail=new a.Models.SendMailControl({weight:200,link:e.links.mailLink}),f.add(b.sendMail));c.user.get("isAgent")&&(b.redirect=new a.Models.RedirectControl({weight:200,link:e.links.redirectLink}),f.add(b.redirect),b.history=new a.Models.HistoryControl({weight:180,link:e.links.historyLink}),f.add(b.history));
+b.sound=new a.Models.SoundControl({weight:160});f.add(b.sound);b.refresh=new a.Models.RefreshControl({weight:140});f.add(b.refresh);e.links.sslLink&&(b.secureMode=new a.Models.SecureModeControl({weight:120,link:e.links.sslLink}),f.add(b.secureMode));b.close=new a.Models.CloseControl({weight:100});f.add(b.close);g.Collections.controls=f;d.controlsRegion.show(new a.Views.ControlsCollection({collection:f}));h.message=new a.Models.StatusMessage({hideTimeout:5E3});h.typing=new a.Models.StatusTyping({hideTimeout:5E3});
+g.Collections.status=new a.Collections.Status([h.message,h.typing]);d.statusRegion.show(new a.Views.StatusCollection({collection:g.Collections.status}));c.user.get("isAgent")||(c.avatar=new a.Models.Avatar,d.avatarRegion.show(new a.Views.Avatar({model:c.avatar})));g.Collections.messages=new a.Collections.Messages;c.messageForm=new a.Models.MessageForm(e.messageForm);d.messageFormRegion.show(new a.Views.MessageForm({model:c.messageForm}));d.messagesRegion.show(new a.Views.MessagesCollection({collection:g.Collections.messages}));
+c.sound=new a.Models.Sound;d.soundRegion.show(new a.Views.Sound({model:c.sound}));g.server.callFunctionsPeriodically(function(){var b=a.Objects.Models.thread,c=a.Objects.Models.user;return[{"function":"update",arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:b.get("id"),token:b.get("token"),lastId:b.get("lastId"),typed:c.get("typing"),user:!c.get("isAgent")}}]},function(b){b.errorCode?a.Objects.Models.Status.message.setMessage(b.errorMessage||"refresh failed"):(b.typing&&
+a.Objects.Models.Status.typing.show(),a.Objects.Models.user.set({canPost:b.canPost||!1}))})});d.on("start",function(){a.Objects.server.runUpdater()});a.Application=d})(Mibew,Backbone,_);
diff --git a/src/messenger/webim/js/compiled/chat/collections/messages.js b/src/messenger/webim/js/compiled/chat/collections/messages.js
index 6dcbffd3..c9c68b26 100644
--- a/src/messenger/webim/js/compiled/chat/collections/messages.js
+++ b/src/messenger/webim/js/compiled/chat/collections/messages.js
@@ -5,6 +5,5 @@
  Copyright (c) 2005-2011 Mibew Messenger Community
  License: http://mibew.org/license.php
 */
-(function(b,d,c){b.Collections.Messages=d.Collection.extend({model:b.Models.Message,initialize:function(){b.Objects.server.callFunctionsPeriodically(c.bind(this.updateFunctionBuilder,this),c.bind(this.updateChatState,this));b.Objects.server.registerFunction("updateMessages",c.bind(this.apiUpdateMessages,this))},apiUpdateMessages:function(a){a.lastId&&b.Objects.Models.thread.set({lastId:a.lastId});for(var e=[],c=0,d=a.messages.length;c<d;c++)e.push(new b.Models.Message(a.messages[c]));0<e.length&&
-this.add(e)},updateFunctionBuilder:function(){var a=b.Objects.Models.thread,c=b.Objects.Models.user;return[{"function":"update",arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:a.get("id"),token:a.get("token"),lastId:a.get("lastId"),typed:c.get("typing"),user:!c.get("isAgent")}}]},updateChatState:function(a){a.errorCode?b.Objects.Models.Status.message.setMessage(a.errorMessage||"refresh failed"):(a.typing&&b.Objects.Models.Status.typing.show(),b.Objects.Models.user.set({canPost:a.canPost||
-!1}))},add:function(){var a=Array.prototype.slice.apply(arguments),a=d.Collection.prototype.add.apply(this,a);this.trigger("multiple:add");return a}})})(Mibew,Backbone,_);
+(function(b,d,f){b.Collections.Messages=d.Collection.extend({model:b.Models.Message,initialize:function(){b.Objects.server.callFunctionsPeriodically(f.bind(this.updateMessagesFunctionBuilder,this),f.bind(this.updateMessages,this))},updateMessages:function(a){a.lastId&&b.Objects.Models.thread.set({lastId:a.lastId});for(var c=[],e=0,d=a.messages.length;e<d;e++)c.push(new b.Models.Message(a.messages[e]));0<c.length&&this.add(c)},updateMessagesFunctionBuilder:function(){var a=b.Objects.Models.thread,
+c=b.Objects.Models.user;return[{"function":"updateMessages",arguments:{"return":{messages:"messages",lastId:"lastId"},references:{},threadId:a.get("id"),token:a.get("token"),lastId:a.get("lastId"),user:!c.get("isAgent")}}]},add:function(){var a=Array.prototype.slice.apply(arguments),a=d.Collection.prototype.add.apply(this,a);this.trigger("multiple:add");return a}})})(Mibew,Backbone,_);
diff --git a/src/messenger/webim/js/compiled/chat_app.js b/src/messenger/webim/js/compiled/chat_app.js
index 221edcd6..ea1f3e56 100644
--- a/src/messenger/webim/js/compiled/chat_app.js
+++ b/src/messenger/webim/js/compiled/chat_app.js
@@ -116,9 +116,8 @@ MibewAPIChatInteraction=function(){this.obligatoryArguments={"*":{threadId:null,
  Copyright (c) 2005-2011 Mibew Messenger Community
  License: http://mibew.org/license.php
 */
-(function(b,d,c){b.Collections.Messages=d.Collection.extend({model:b.Models.Message,initialize:function(){b.Objects.server.callFunctionsPeriodically(c.bind(this.updateFunctionBuilder,this),c.bind(this.updateChatState,this));b.Objects.server.registerFunction("updateMessages",c.bind(this.apiUpdateMessages,this))},apiUpdateMessages:function(a){a.lastId&&b.Objects.Models.thread.set({lastId:a.lastId});for(var e=[],c=0,d=a.messages.length;c<d;c++)e.push(new b.Models.Message(a.messages[c]));0<e.length&&
-this.add(e)},updateFunctionBuilder:function(){var a=b.Objects.Models.thread,c=b.Objects.Models.user;return[{"function":"update",arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:a.get("id"),token:a.get("token"),lastId:a.get("lastId"),typed:c.get("typing"),user:!c.get("isAgent")}}]},updateChatState:function(a){a.errorCode?b.Objects.Models.Status.message.setMessage(a.errorMessage||"refresh failed"):(a.typing&&b.Objects.Models.Status.typing.show(),b.Objects.Models.user.set({canPost:a.canPost||
-!1}))},add:function(){var a=Array.prototype.slice.apply(arguments),a=d.Collection.prototype.add.apply(this,a);this.trigger("multiple:add");return a}})})(Mibew,Backbone,_);
+(function(b,d,f){b.Collections.Messages=d.Collection.extend({model:b.Models.Message,initialize:function(){b.Objects.server.callFunctionsPeriodically(f.bind(this.updateMessagesFunctionBuilder,this),f.bind(this.updateMessages,this))},updateMessages:function(a){a.lastId&&b.Objects.Models.thread.set({lastId:a.lastId});for(var c=[],e=0,d=a.messages.length;e<d;e++)c.push(new b.Models.Message(a.messages[e]));0<c.length&&this.add(c)},updateMessagesFunctionBuilder:function(){var a=b.Objects.Models.thread,
+c=b.Objects.Models.user;return[{"function":"updateMessages",arguments:{"return":{messages:"messages",lastId:"lastId"},references:{},threadId:a.get("id"),token:a.get("token"),lastId:a.get("lastId"),user:!c.get("isAgent")}}]},add:function(){var a=Array.prototype.slice.apply(arguments),a=d.Collection.prototype.add.apply(this,a);this.trigger("multiple:add");return a}})})(Mibew,Backbone,_);
 /*
  This file is part of Mibew Messenger project.
  http://mibew.org
@@ -250,8 +249,9 @@ c=""!=this.ui.message.val();c!=a.get("typing")&&a.set({typing:c})},setFocus:func
  Copyright (c) 2005-2011 Mibew Messenger Community
  License: http://mibew.org/license.php
 */
-(function(a,j,k){var f=new j.Marionette.Application;f.addRegions({controlsRegion:"#controls-region",avatarRegion:"#avatar-region",messagesRegion:a.Regions.Messages,statusRegion:"#status-region",messageFormRegion:"#message-form-region",soundRegion:"#sound-region"});f.addInitializer(function(d){var g=a.Objects,c=a.Objects.Models,b=a.Objects.Models.Controls,h=a.Objects.Models.Status;g.server=new a.Server(k.extend({interactionType:MibewAPIChatInteraction},d.server));c.thread=new a.Models.Thread(d.thread);
-c.user=new a.Models.ChatUser(d.user);c.page=new a.Models.Page(d.page);var e=new a.Collections.Controls;c.user.get("isAgent")||(b.userName=new a.Models.UserNameControl({weight:220}),e.add(b.userName),b.sendMail=new a.Models.SendMailControl({weight:200,link:d.links.mailLink}),e.add(b.sendMail));c.user.get("isAgent")&&(b.redirect=new a.Models.RedirectControl({weight:200,link:d.links.redirectLink}),e.add(b.redirect),b.history=new a.Models.HistoryControl({weight:180,link:d.links.historyLink}),e.add(b.history));
-b.sound=new a.Models.SoundControl({weight:160});e.add(b.sound);b.refresh=new a.Models.RefreshControl({weight:140});e.add(b.refresh);d.links.sslLink&&(b.secureMode=new a.Models.SecureModeControl({weight:120,link:d.links.sslLink}),e.add(b.secureMode));b.close=new a.Models.CloseControl({weight:100});e.add(b.close);g.Collections.controls=e;f.controlsRegion.show(new a.Views.ControlsCollection({collection:e}));h.message=new a.Models.StatusMessage({hideTimeout:5E3});h.typing=new a.Models.StatusTyping({hideTimeout:5E3});
-g.Collections.status=new a.Collections.Status([h.message,h.typing]);f.statusRegion.show(new a.Views.StatusCollection({collection:g.Collections.status}));c.user.get("isAgent")||(c.avatar=new a.Models.Avatar,f.avatarRegion.show(new a.Views.Avatar({model:c.avatar})));g.Collections.messages=new a.Collections.Messages;c.messageForm=new a.Models.MessageForm(d.messageForm);f.messageFormRegion.show(new a.Views.MessageForm({model:c.messageForm}));f.messagesRegion.show(new a.Views.MessagesCollection({collection:g.Collections.messages}));
-c.sound=new a.Models.Sound;f.soundRegion.show(new a.Views.Sound({model:c.sound}));g.server.runUpdater()});a.Application=f})(Mibew,Backbone,_);
+(function(a,j,k){var d=new j.Marionette.Application;d.addRegions({controlsRegion:"#controls-region",avatarRegion:"#avatar-region",messagesRegion:a.Regions.Messages,statusRegion:"#status-region",messageFormRegion:"#message-form-region",soundRegion:"#sound-region"});d.addInitializer(function(e){var g=a.Objects,c=a.Objects.Models,b=a.Objects.Models.Controls,h=a.Objects.Models.Status;g.server=new a.Server(k.extend({interactionType:MibewAPIChatInteraction},e.server));c.thread=new a.Models.Thread(e.thread);
+c.user=new a.Models.ChatUser(e.user);c.page=new a.Models.Page(e.page);var f=new a.Collections.Controls;c.user.get("isAgent")||(b.userName=new a.Models.UserNameControl({weight:220}),f.add(b.userName),b.sendMail=new a.Models.SendMailControl({weight:200,link:e.links.mailLink}),f.add(b.sendMail));c.user.get("isAgent")&&(b.redirect=new a.Models.RedirectControl({weight:200,link:e.links.redirectLink}),f.add(b.redirect),b.history=new a.Models.HistoryControl({weight:180,link:e.links.historyLink}),f.add(b.history));
+b.sound=new a.Models.SoundControl({weight:160});f.add(b.sound);b.refresh=new a.Models.RefreshControl({weight:140});f.add(b.refresh);e.links.sslLink&&(b.secureMode=new a.Models.SecureModeControl({weight:120,link:e.links.sslLink}),f.add(b.secureMode));b.close=new a.Models.CloseControl({weight:100});f.add(b.close);g.Collections.controls=f;d.controlsRegion.show(new a.Views.ControlsCollection({collection:f}));h.message=new a.Models.StatusMessage({hideTimeout:5E3});h.typing=new a.Models.StatusTyping({hideTimeout:5E3});
+g.Collections.status=new a.Collections.Status([h.message,h.typing]);d.statusRegion.show(new a.Views.StatusCollection({collection:g.Collections.status}));c.user.get("isAgent")||(c.avatar=new a.Models.Avatar,d.avatarRegion.show(new a.Views.Avatar({model:c.avatar})));g.Collections.messages=new a.Collections.Messages;c.messageForm=new a.Models.MessageForm(e.messageForm);d.messageFormRegion.show(new a.Views.MessageForm({model:c.messageForm}));d.messagesRegion.show(new a.Views.MessagesCollection({collection:g.Collections.messages}));
+c.sound=new a.Models.Sound;d.soundRegion.show(new a.Views.Sound({model:c.sound}));g.server.callFunctionsPeriodically(function(){var b=a.Objects.Models.thread,c=a.Objects.Models.user;return[{"function":"update",arguments:{"return":{typing:"typing",canPost:"canPost"},references:{},threadId:b.get("id"),token:b.get("token"),lastId:b.get("lastId"),typed:c.get("typing"),user:!c.get("isAgent")}}]},function(b){b.errorCode?a.Objects.Models.Status.message.setMessage(b.errorMessage||"refresh failed"):(b.typing&&
+a.Objects.Models.Status.typing.show(),a.Objects.Models.user.set({canPost:b.canPost||!1}))})});d.on("start",function(){a.Objects.server.runUpdater()});a.Application=d})(Mibew,Backbone,_);
diff --git a/src/messenger/webim/js/source/chat/app.js b/src/messenger/webim/js/source/chat/app.js
index 9bf989c1..bde3de9c 100644
--- a/src/messenger/webim/js/source/chat/app.js
+++ b/src/messenger/webim/js/source/chat/app.js
@@ -169,8 +169,56 @@
         }));
 
 
-        // Run server updater
-        objs.server.runUpdater();
+        // TODO: May be move it somewhere else
+        // Periodically call update function at the server side
+        objs.server.callFunctionsPeriodically(
+            function() {
+                // Get thread and user objects
+                var thread = Mibew.Objects.Models.thread;
+                var user = Mibew.Objects.Models.user;
+
+                // Build functions list
+                return [
+                    {
+                        "function": "update",
+                        "arguments": {
+                            "return": {
+                                'typing': 'typing',
+                                'canPost': 'canPost'
+                            },
+                            "references": {},
+                            "threadId": thread.get('id'),
+                            "token": thread.get('token'),
+                            "lastId": thread.get('lastId'),
+                            "typed": user.get('typing'),
+                            "user": (! user.get('isAgent'))
+                        }
+                    }
+                ]
+            },
+            function(args) {
+                // Check if there was an error
+                if (args.errorCode) {
+                    Mibew.Objects.Models.Status.message.setMessage(
+                        args.errorMessage || 'refresh failed'
+                    );
+                    return;
+                }
+                // Update typing status
+                if (args.typing) {
+                    Mibew.Objects.Models.Status.typing.show();
+                }
+                // Update user
+                Mibew.Objects.Models.user.set({
+                    canPost: args.canPost || false
+                });
+            }
+        );
+    });
+
+    App.on('start', function() {
+        // Run Server updater
+        Mibew.Objects.server.runUpdater();
     });
 
     Mibew.Application = App;
diff --git a/src/messenger/webim/js/source/chat/collections/messages.js b/src/messenger/webim/js/source/chat/collections/messages.js
index cec0d078..b256e278 100644
--- a/src/messenger/webim/js/source/chat/collections/messages.js
+++ b/src/messenger/webim/js/source/chat/collections/messages.js
@@ -24,25 +24,18 @@
              * Collection initializer.
              */
             initialize: function() {
-                // Add periodic functions
+                // Periodically try to get new messages
                 Mibew.Objects.server.callFunctionsPeriodically(
-                    _.bind(this.updateFunctionBuilder, this),
-                    _.bind(this.updateChatState, this)
-                );
-
-                // Register API functions
-                Mibew.Objects.server.registerFunction(
-                    'updateMessages',
-                    _.bind(this.apiUpdateMessages, this)
+                    _.bind(this.updateMessagesFunctionBuilder, this),
+                    _.bind(this.updateMessages, this)
                 );
             },
 
             /**
              * Update messages if they are exist.
-             * This is an API function.
              * @param args {Object} An object of passed arguments
              */
-            apiUpdateMessages: function(args) {
+            updateMessages: function(args) {
 
                 // Update last message id
                 if (args.lastId) {
@@ -66,11 +59,11 @@
             },
 
             /**
-             * Builds update function, that should be called periodically at
-             * the server side
+             * Builds updateMessages function, that should be called
+             * periodically at the server side
              * @returns {Object[]} Array of functions objects
              */
-            updateFunctionBuilder: function() {
+            updateMessagesFunctionBuilder: function() {
                 // Get thread and user objects
                 var thread = Mibew.Objects.Models.thread;
                 var user = Mibew.Objects.Models.user;
@@ -78,45 +71,22 @@
                 // Build functions list
                 return [
                     {
-                        "function": "update",
+                        "function": "updateMessages",
                         "arguments": {
                             "return": {
-                                'typing': 'typing',
-                                'canPost': 'canPost'
+                                'messages': 'messages',
+                                'lastId': 'lastId'
                             },
                             "references": {},
                             "threadId": thread.get('id'),
                             "token": thread.get('token'),
                             "lastId": thread.get('lastId'),
-                            "typed": user.get('typing'),
                             "user": (! user.get('isAgent'))
                         }
                     }
                 ];
             },
 
-            /**
-             * Updates chat status
-             * @param {Object} args Arguments passed from the server
-             */
-            updateChatState: function(args) {
-                // Check if there was an error
-                if (args.errorCode) {
-                    Mibew.Objects.Models.Status.message.setMessage(
-                        args.errorMessage || 'refresh failed'
-                    );
-                    return;
-                }
-                // Update typing status
-                if (args.typing) {
-                    Mibew.Objects.Models.Status.typing.show();
-                }
-                // Update user
-                Mibew.Objects.Models.user.set({
-                    canPost: args.canPost || false
-                });
-            },
-
             /**
              * Override Backbone.Collection.add method to call additional event
              */
diff --git a/src/messenger/webim/libs/classes/thread_processor.php b/src/messenger/webim/libs/classes/thread_processor.php
index d49c0be1..72211c36 100644
--- a/src/messenger/webim/libs/classes/thread_processor.php
+++ b/src/messenger/webim/libs/classes/thread_processor.php
@@ -203,39 +203,6 @@ class ThreadProcessor extends ClientSideProcessor {
 		}
 	}
 
-	/**
-	 * Send new messages to window
-	 *
-	 * Call updateMessages at window side
-	 *
-	 * @global string $webim_encoding
-	 * @param Thread $thread Messages sends to this thread
-	 * @param boolead $is_user TRUE if messages sends to user and FALSE otherwise
-	 * @param int $last_message_id Id of the last sent message
-	 */
-	protected function sendMessages(Thread $thread, $is_user, $last_message_id) {
-		$messages = $thread->getMessages($is_user, $last_message_id);
-		if (! empty($messages)) {
-			// Send messages
-			$this->responses[] = array(
-				'token' => md5(time() . rand()),
-				'functions' => array(
-					array(
-						'function' => 'updateMessages',
-						'arguments' => array(
-							'threadId' => $thread->id,
-							'token' => $thread->lastToken,
-							'return' => array(),
-							'references' => array(),
-							'messages' => $messages,
-							'lastId' => $last_message_id
-						)
-					)
-				)
-			);
-		}
-	}
-
 	/**
 	 * Update chat window state. API function
 	 *
@@ -255,7 +222,7 @@ class ThreadProcessor extends ClientSideProcessor {
 		$thread = self::getThread($args['threadId'], $args['token']);
 
 		// Check variables
-		self::checkParams($args, array('user', 'typed', 'lastId'));
+		self::checkParams($args, array('user', 'typed'));
 
 		if (! $args['user']) {
 			$operator = self::checkOperator();
@@ -264,9 +231,6 @@ class ThreadProcessor extends ClientSideProcessor {
 
 		$thread->ping($args['user'], $args['typed']);
 
-		// Update messages
-		$this->sendMessages($thread, $args['user'], $args['lastId']);
-
 		// Create requests key
 		$requests_key = false;
 		if ($args['user']) {
@@ -299,6 +263,40 @@ class ThreadProcessor extends ClientSideProcessor {
 		);
 	}
 
+	/**
+	 * Send new messages to window. API function
+	 *
+	 * @param array $args Associative array of arguments. It must contains following keys:
+	 *  - 'threadId': Id of the thread related to chat window
+	 *  - 'token': last thread token
+	 *  - 'user': TRUE if window used by user and FALSE otherwise
+	 *  - 'lastId': last sent message id
+	 */
+	protected function apiUpdateMessages($args) {
+		// Load thread
+		$thread = self::getThread($args['threadId'], $args['token']);
+
+		// Check variables
+		self::checkParams($args, array('user', 'lastId'));
+
+		// Check access
+		if (! $args['user']) {
+			self::checkOperator();
+		}
+
+		// Send new messages
+		$last_message_id = $args['lastId'];
+		$messages = $thread->getMessages($args['user'], $last_message_id);
+		if (empty($messages)) {
+			$messages = array();
+		}
+
+		return array(
+			'messages' => $messages,
+			'lastId' => $last_message_id
+		);
+	}
+
 	/**
 	 * Post message to thread. API function
 	 *