Some refactoring of chat states work. updates #292
- Don't add a timeout for the GONE state. - Change state to GONE when the user closes the chat box. - Change the state to inactive when the user minimizes the chat box. - Change the state to active when the users maximizes the chat box. - Add more tests for chat states.
This commit is contained in:
parent
2b2b176189
commit
b4d53aaa94
89
converse.js
89
converse.js
@ -208,7 +208,7 @@
|
|||||||
var PAUSED = 'paused';
|
var PAUSED = 'paused';
|
||||||
var GONE = 'gone';
|
var GONE = 'gone';
|
||||||
this.TIMEOUTS = { // Set as module attr so that we can override in tests.
|
this.TIMEOUTS = { // Set as module attr so that we can override in tests.
|
||||||
'PAUSED': 30000,
|
'PAUSED': 20000,
|
||||||
'INACTIVE': 90000,
|
'INACTIVE': 90000,
|
||||||
'GONE': 510000
|
'GONE': 510000
|
||||||
};
|
};
|
||||||
@ -722,7 +722,9 @@
|
|||||||
this.messages.browserStorage = new Backbone.BrowserStorage[converse.storage](
|
this.messages.browserStorage = new Backbone.BrowserStorage[converse.storage](
|
||||||
b64_sha1('converse.messages'+this.get('jid')+converse.bare_jid));
|
b64_sha1('converse.messages'+this.get('jid')+converse.bare_jid));
|
||||||
this.save({
|
this.save({
|
||||||
'chat_state': ACTIVE,
|
// The chat_state will be set to ACTIVE once the chat box is opened
|
||||||
|
// and we listen for change:chat_state, so shouldn't set it to ACTIVE here.
|
||||||
|
'chat_state': undefined,
|
||||||
'box_id' : b64_sha1(this.get('jid')),
|
'box_id' : b64_sha1(this.get('jid')),
|
||||||
'height': height,
|
'height': height,
|
||||||
'minimized': this.get('minimized') || false,
|
'minimized': this.get('minimized') || false,
|
||||||
@ -973,6 +975,8 @@
|
|||||||
'click .close-chatbox-button': 'close',
|
'click .close-chatbox-button': 'close',
|
||||||
'click .toggle-chatbox-button': 'minimize',
|
'click .toggle-chatbox-button': 'minimize',
|
||||||
'keypress textarea.chat-textarea': 'keyPressed',
|
'keypress textarea.chat-textarea': 'keyPressed',
|
||||||
|
'focus textarea.chat-textarea': 'chatBoxFocused',
|
||||||
|
'blur textarea.chat-textarea': 'chatBoxBlurred',
|
||||||
'click .toggle-smiley': 'toggleEmoticonMenu',
|
'click .toggle-smiley': 'toggleEmoticonMenu',
|
||||||
'click .toggle-smiley ul li': 'insertEmoticon',
|
'click .toggle-smiley ul li': 'insertEmoticon',
|
||||||
'click .toggle-clear': 'clearMessages',
|
'click .toggle-clear': 'clearMessages',
|
||||||
@ -1146,8 +1150,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
sendMessageStanza: function (text) {
|
sendMessageStanza: function (text) {
|
||||||
/*
|
/* Sends the actual XML stanza to the XMPP server.
|
||||||
* Sends the actual XML stanza to the XMPP server.
|
|
||||||
*/
|
*/
|
||||||
// TODO: Look in ChatPartners to see what resources we have for the recipient.
|
// TODO: Look in ChatPartners to see what resources we have for the recipient.
|
||||||
// if we have one resource, we sent to only that resources, if we have multiple
|
// if we have one resource, we sent to only that resources, if we have multiple
|
||||||
@ -1207,9 +1210,9 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
sendChatState: function () {
|
sendChatState: function () {
|
||||||
/* XEP-0085 Chat State Notifications.
|
/* Sends a message with the status of the user in this chat session
|
||||||
* Sends a message with the status of the user in this chat session
|
|
||||||
* as taken from the 'chat_state' attribute of the chat box.
|
* as taken from the 'chat_state' attribute of the chat box.
|
||||||
|
* See XEP-0085 Chat State Notifications.
|
||||||
*/
|
*/
|
||||||
converse.connection.send(
|
converse.connection.send(
|
||||||
$msg({'to':this.model.get('jid'), 'type': 'chat'})
|
$msg({'to':this.model.get('jid'), 'type': 'chat'})
|
||||||
@ -1217,33 +1220,40 @@
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
escalateChatState: function () {
|
setChatState: function (state, no_save) {
|
||||||
/* XEP-0085 Chat State Notifications.
|
/* Mutator for setting the chat state of this chat session.
|
||||||
* This method gets called asynchronously via setTimeout. It escalates the
|
* Handles clearing of any chat state notification timeouts and
|
||||||
* chat state and depending on the current state can set a new timeout.
|
* setting new ones if necessary.
|
||||||
|
* Timeouts are set when the state being set is COMPOSING or PAUSED.
|
||||||
|
* After the timeout, COMPOSING will become PAUSED and PAUSED will become INACTIVE.
|
||||||
|
* See XEP-0085 Chat State Notifications.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* (string) state - The chat state (consts ACTIVE, COMPOSING, PAUSED, INACTIVE, GONE)
|
||||||
|
* (no_save) no_save - Just do the cleanup or setup but don't actually save the state.
|
||||||
*/
|
*/
|
||||||
|
if (_.contains([ACTIVE, INACTIVE, GONE], state)) {
|
||||||
|
if (typeof this.chat_state_timeout !== 'undefined') {
|
||||||
|
clearTimeout(this.chat_state_timeout);
|
||||||
delete this.chat_state_timeout;
|
delete this.chat_state_timeout;
|
||||||
if (this.model.get('chat_state') == COMPOSING) {
|
|
||||||
this.model.set('chat_state', PAUSED);
|
|
||||||
// From now on, if no activity in 2 mins, we'll set the
|
|
||||||
// state to <inactive>
|
|
||||||
this.chat_state_timeout = setTimeout($.proxy(this.escalateChatState, this), converse.TIMEOUTS.INACTIVE);
|
|
||||||
} else if (this.model.get('chat_state') == PAUSED) {
|
|
||||||
this.model.set('chat_state', INACTIVE);
|
|
||||||
// From now on, if no activity in 10 mins, we'll set the
|
|
||||||
// state to <gone>
|
|
||||||
this.chat_state_timeout = setTimeout($.proxy(this.escalateChatState, this), converse.TIMEOUTS.GONE);
|
|
||||||
} else if (this.model.get('chat_state') == INACTIVE) {
|
|
||||||
this.model.set('chat_state', GONE);
|
|
||||||
}
|
}
|
||||||
|
} else if (state === COMPOSING) {
|
||||||
|
this.chat_state_timeout = setTimeout(
|
||||||
|
$.proxy(this.setChatState, this), converse.TIMEOUTS.PAUSED, PAUSED);
|
||||||
|
} else if (state === PAUSED) {
|
||||||
|
this.chat_state_timeout = setTimeout(
|
||||||
|
$.proxy(this.setChatState, this), converse.TIMEOUTS.INACTIVE, INACTIVE);
|
||||||
|
}
|
||||||
|
if (!no_save && this.model.get('chat_state') != state) {
|
||||||
|
this.model.set('chat_state', state);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
keyPressed: function (ev) {
|
keyPressed: function (ev) {
|
||||||
|
/* Event handler for when a key is pressed in a chat box textarea.
|
||||||
|
*/
|
||||||
var $textarea = $(ev.target), message;
|
var $textarea = $(ev.target), message;
|
||||||
if (typeof this.chat_state_timeout !== 'undefined') {
|
|
||||||
clearTimeout(this.chat_state_timeout);
|
|
||||||
delete this.chat_state_timeout; // XXX: Necessary?
|
|
||||||
}
|
|
||||||
if (ev.keyCode == KEY.ENTER) {
|
if (ev.keyCode == KEY.ENTER) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
message = $textarea.val();
|
message = $textarea.val();
|
||||||
@ -1256,19 +1266,24 @@
|
|||||||
}
|
}
|
||||||
converse.emit('messageSend', message);
|
converse.emit('messageSend', message);
|
||||||
}
|
}
|
||||||
this.model.set('chat_state', ACTIVE);
|
this.setChatState(ACTIVE);
|
||||||
} else if (!this.model.get('chatroom')) {
|
} else if (!this.model.get('chatroom')) { // chat state data is currently only for single user chat
|
||||||
// chat state data is currently only for single user chat
|
|
||||||
// Concerning group chat: http://xmpp.org/extensions/xep-0085.html#bizrules-groupchat
|
|
||||||
this.chat_state_timeout = setTimeout($.proxy(this.escalateChatState, this), converse.TIMEOUTS.PAUSED);
|
|
||||||
if (this.model.get('chat_state') != COMPOSING && ev.keyCode != KEY.FORWARD_SLASH) {
|
|
||||||
// Set chat state to composing if keyCode is not a forward-slash
|
// Set chat state to composing if keyCode is not a forward-slash
|
||||||
// (which would imply an internal command and not a message).
|
// (which would imply an internal command and not a message).
|
||||||
this.model.set('chat_state', COMPOSING);
|
this.setChatState(COMPOSING, ev.keyCode==KEY.FORWARD_SLASH);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
chatBoxFocused: function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.setChatState(ACTIVE);
|
||||||
|
},
|
||||||
|
|
||||||
|
chatBoxBlurred: function (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.setChatState(INACTIVE);
|
||||||
|
},
|
||||||
|
|
||||||
onDragResizeStart: function (ev) {
|
onDragResizeStart: function (ev) {
|
||||||
if (!converse.allow_dragresize) { return true; }
|
if (!converse.allow_dragresize) { return true; }
|
||||||
// Record element attributes for mouseMove().
|
// Record element attributes for mouseMove().
|
||||||
@ -1446,6 +1461,7 @@
|
|||||||
} else {
|
} else {
|
||||||
this.model.trigger('hide');
|
this.model.trigger('hide');
|
||||||
}
|
}
|
||||||
|
this.setChatState(GONE);
|
||||||
converse.emit('chatBoxClosed', this);
|
converse.emit('chatBoxClosed', this);
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
@ -1454,7 +1470,7 @@
|
|||||||
// Restores a minimized chat box
|
// Restores a minimized chat box
|
||||||
this.$el.insertAfter(converse.chatboxviews.get("controlbox").$el).show('fast', $.proxy(function () {
|
this.$el.insertAfter(converse.chatboxviews.get("controlbox").$el).show('fast', $.proxy(function () {
|
||||||
converse.refreshWebkit();
|
converse.refreshWebkit();
|
||||||
this.focus();
|
this.setChatState(ACTIVE).focus();
|
||||||
converse.emit('chatBoxMaximized', this);
|
converse.emit('chatBoxMaximized', this);
|
||||||
}, this));
|
}, this));
|
||||||
},
|
},
|
||||||
@ -1462,7 +1478,7 @@
|
|||||||
minimize: function (ev) {
|
minimize: function (ev) {
|
||||||
if (ev && ev.preventDefault) { ev.preventDefault(); }
|
if (ev && ev.preventDefault) { ev.preventDefault(); }
|
||||||
// Minimizes a chat box
|
// Minimizes a chat box
|
||||||
this.model.minimize();
|
this.setChatState(INACTIVE).model.minimize();
|
||||||
this.$el.hide('fast', converse.refreshwebkit);
|
this.$el.hide('fast', converse.refreshwebkit);
|
||||||
converse.emit('chatBoxMinimized', this);
|
converse.emit('chatBoxMinimized', this);
|
||||||
},
|
},
|
||||||
@ -1591,6 +1607,7 @@
|
|||||||
this.model.save();
|
this.model.save();
|
||||||
this.initDragResize();
|
this.initDragResize();
|
||||||
}
|
}
|
||||||
|
this.setChatState(ACTIVE);
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
199
spec/chatbox.js
199
spec/chatbox.js
@ -408,43 +408,6 @@
|
|||||||
runs(function () {});
|
runs(function () {});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can indicate a chat state notification", $.proxy(function () {
|
|
||||||
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
|
|
||||||
spyOn(converse, 'emit');
|
|
||||||
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
|
||||||
|
|
||||||
// <composing> state
|
|
||||||
var msg = $msg({
|
|
||||||
from: sender_jid,
|
|
||||||
to: this.connection.jid,
|
|
||||||
type: 'chat',
|
|
||||||
id: (new Date()).getTime()
|
|
||||||
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
|
||||||
|
|
||||||
this.chatboxes.onMessage(msg);
|
|
||||||
expect(converse.emit).toHaveBeenCalledWith('message', msg);
|
|
||||||
var chatboxview = this.chatboxviews.get(sender_jid);
|
|
||||||
expect(chatboxview).toBeDefined();
|
|
||||||
// Check that the notification appears inside the chatbox in the DOM
|
|
||||||
var $events = chatboxview.$el.find('.chat-event');
|
|
||||||
expect($events.length).toBe(1);
|
|
||||||
expect($events.text()).toEqual(mock.cur_names[1].split(' ')[0] + ' is typing');
|
|
||||||
|
|
||||||
// <paused> state
|
|
||||||
msg = $msg({
|
|
||||||
from: sender_jid,
|
|
||||||
to: this.connection.jid,
|
|
||||||
type: 'chat',
|
|
||||||
id: (new Date()).getTime()
|
|
||||||
}).c('body').c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
|
||||||
|
|
||||||
this.chatboxes.onMessage(msg);
|
|
||||||
expect(converse.emit).toHaveBeenCalledWith('message', msg);
|
|
||||||
$events = chatboxview.$el.find('.chat-event');
|
|
||||||
expect($events.length).toBe(1);
|
|
||||||
expect($events.text()).toEqual(mock.cur_names[1].split(' ')[0] + ' has stopped typing');
|
|
||||||
}, converse));
|
|
||||||
|
|
||||||
it("can be received which will open a chatbox and be displayed inside it", $.proxy(function () {
|
it("can be received which will open a chatbox and be displayed inside it", $.proxy(function () {
|
||||||
spyOn(converse, 'emit');
|
spyOn(converse, 'emit');
|
||||||
var message = 'This is a received message';
|
var message = 'This is a received message';
|
||||||
@ -731,7 +694,38 @@
|
|||||||
|
|
||||||
describe("A Chat Status Notification", $.proxy(function () {
|
describe("A Chat Status Notification", $.proxy(function () {
|
||||||
|
|
||||||
describe("A composing notifciation", $.proxy(function () {
|
describe("An active notification", $.proxy(function () {
|
||||||
|
it("is sent when the user opens a chat box", $.proxy(function () {
|
||||||
|
spyOn(converse.connection, 'send');
|
||||||
|
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
test_utils.openChatBoxFor(contact_jid);
|
||||||
|
var view = this.chatboxviews.get(contact_jid);
|
||||||
|
expect(view.model.get('chat_state')).toBe('active');
|
||||||
|
expect(converse.connection.send).toHaveBeenCalled();
|
||||||
|
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
|
||||||
|
expect($stanza.attr('to')).toBe(contact_jid);
|
||||||
|
expect($stanza.children().length).toBe(1);
|
||||||
|
expect($stanza.children().prop('tagName')).toBe('active');
|
||||||
|
}, converse));
|
||||||
|
|
||||||
|
it("is sent when the user maximizes a minimized a chat box", $.proxy(function () {
|
||||||
|
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
test_utils.openChatBoxFor(contact_jid);
|
||||||
|
var view = this.chatboxviews.get(contact_jid);
|
||||||
|
view.minimize();
|
||||||
|
expect(view.model.get('chat_state')).toBe('inactive');
|
||||||
|
spyOn(converse.connection, 'send');
|
||||||
|
view.maximize();
|
||||||
|
expect(view.model.get('chat_state')).toBe('active');
|
||||||
|
expect(converse.connection.send).toHaveBeenCalled();
|
||||||
|
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
|
||||||
|
expect($stanza.attr('to')).toBe(contact_jid);
|
||||||
|
expect($stanza.children().length).toBe(1);
|
||||||
|
expect($stanza.children().prop('tagName')).toBe('active');
|
||||||
|
}, converse));
|
||||||
|
}, converse));
|
||||||
|
|
||||||
|
describe("A composing notification", $.proxy(function () {
|
||||||
it("is sent as soon as the user starts typing a message which is not a command", $.proxy(function () {
|
it("is sent as soon as the user starts typing a message which is not a command", $.proxy(function () {
|
||||||
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
test_utils.openChatBoxFor(contact_jid);
|
test_utils.openChatBoxFor(contact_jid);
|
||||||
@ -757,6 +751,28 @@
|
|||||||
expect(view.model.get('chat_state')).toBe('composing');
|
expect(view.model.get('chat_state')).toBe('composing');
|
||||||
expect(converse.emit.callCount, 1);
|
expect(converse.emit.callCount, 1);
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
|
it("will be shown if received", $.proxy(function () {
|
||||||
|
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
|
||||||
|
spyOn(converse, 'emit');
|
||||||
|
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
|
||||||
|
// <composing> state
|
||||||
|
var msg = $msg({
|
||||||
|
from: sender_jid,
|
||||||
|
to: this.connection.jid,
|
||||||
|
type: 'chat',
|
||||||
|
id: (new Date()).getTime()
|
||||||
|
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||||
|
this.chatboxes.onMessage(msg);
|
||||||
|
expect(converse.emit).toHaveBeenCalledWith('message', msg);
|
||||||
|
var chatboxview = this.chatboxviews.get(sender_jid);
|
||||||
|
expect(chatboxview).toBeDefined();
|
||||||
|
// Check that the notification appears inside the chatbox in the DOM
|
||||||
|
var $events = chatboxview.$el.find('.chat-event');
|
||||||
|
expect($events.length).toBe(1);
|
||||||
|
expect($events.text()).toEqual(mock.cur_names[1].split(' ')[0] + ' is typing');
|
||||||
|
}, converse));
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
describe("A paused notification", $.proxy(function () {
|
describe("A paused notification", $.proxy(function () {
|
||||||
@ -784,6 +800,26 @@
|
|||||||
expect($stanza.children().prop('tagName')).toBe('paused');
|
expect($stanza.children().prop('tagName')).toBe('paused');
|
||||||
});
|
});
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
|
it("will be shown if received", $.proxy(function () {
|
||||||
|
// TODO: only show paused state if the previous state was composing
|
||||||
|
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
|
||||||
|
spyOn(converse, 'emit');
|
||||||
|
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
// <paused> state
|
||||||
|
msg = $msg({
|
||||||
|
from: sender_jid,
|
||||||
|
to: this.connection.jid,
|
||||||
|
type: 'chat',
|
||||||
|
id: (new Date()).getTime()
|
||||||
|
}).c('body').c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||||
|
this.chatboxes.onMessage(msg);
|
||||||
|
expect(converse.emit).toHaveBeenCalledWith('message', msg);
|
||||||
|
var chatboxview = this.chatboxviews.get(sender_jid);
|
||||||
|
$events = chatboxview.$el.find('.chat-event');
|
||||||
|
expect($events.length).toBe(1);
|
||||||
|
expect($events.text()).toEqual(mock.cur_names[1].split(' ')[0] + ' has stopped typing');
|
||||||
|
}, converse));
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
describe("An inactive notifciation", $.proxy(function () {
|
describe("An inactive notifciation", $.proxy(function () {
|
||||||
@ -817,46 +853,79 @@
|
|||||||
expect($stanza.children().prop('tagName')).toBe('inactive');
|
expect($stanza.children().prop('tagName')).toBe('inactive');
|
||||||
});
|
});
|
||||||
}, converse));
|
}, converse));
|
||||||
}, converse));
|
|
||||||
|
|
||||||
describe("An gone notifciation", $.proxy(function () {
|
it("is sent when the user a minimizes a chat box", $.proxy(function () {
|
||||||
it("is sent if the user has stopped typing since 10 minutes", $.proxy(function () {
|
|
||||||
// Make the timeouts shorter so that we can test
|
|
||||||
this.TIMEOUTS.PAUSED = 200;
|
|
||||||
this.TIMEOUTS.INACTIVE = 200;
|
|
||||||
this.TIMEOUTS.GONE = 200;
|
|
||||||
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
test_utils.openChatBoxFor(contact_jid);
|
test_utils.openChatBoxFor(contact_jid);
|
||||||
var view = this.chatboxviews.get(contact_jid);
|
var view = this.chatboxviews.get(contact_jid);
|
||||||
runs(function () {
|
|
||||||
expect(view.model.get('chat_state')).toBe('active');
|
|
||||||
view.keyPressed({
|
|
||||||
target: view.$el.find('textarea.chat-textarea'),
|
|
||||||
keyCode: 1
|
|
||||||
});
|
|
||||||
expect(view.model.get('chat_state')).toBe('composing');
|
|
||||||
});
|
|
||||||
waits(250);
|
|
||||||
runs(function () {
|
|
||||||
expect(view.model.get('chat_state')).toBe('paused');
|
|
||||||
});
|
|
||||||
waits(250);
|
|
||||||
runs(function () {
|
|
||||||
expect(view.model.get('chat_state')).toBe('inactive');
|
|
||||||
spyOn(converse.connection, 'send');
|
spyOn(converse.connection, 'send');
|
||||||
});
|
view.minimize();
|
||||||
waits(250);
|
expect(view.model.get('chat_state')).toBe('inactive');
|
||||||
runs(function () {
|
expect(converse.connection.send).toHaveBeenCalled();
|
||||||
|
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
|
||||||
|
expect($stanza.attr('to')).toBe(contact_jid);
|
||||||
|
expect($stanza.children().length).toBe(1);
|
||||||
|
expect($stanza.children().prop('tagName')).toBe('inactive');
|
||||||
|
}, converse));
|
||||||
|
|
||||||
|
it("will be shown if received", $.proxy(function () {
|
||||||
|
// TODO: only show paused state if the previous state was composing
|
||||||
|
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
|
||||||
|
spyOn(converse, 'emit');
|
||||||
|
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
// <paused> state
|
||||||
|
msg = $msg({
|
||||||
|
from: sender_jid,
|
||||||
|
to: this.connection.jid,
|
||||||
|
type: 'chat',
|
||||||
|
id: (new Date()).getTime()
|
||||||
|
}).c('body').c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||||
|
this.chatboxes.onMessage(msg);
|
||||||
|
expect(converse.emit).toHaveBeenCalledWith('message', msg);
|
||||||
|
var chatboxview = this.chatboxviews.get(sender_jid);
|
||||||
|
$events = chatboxview.$el.find('.chat-event');
|
||||||
|
expect($events.length).toBe(1);
|
||||||
|
expect($events.text()).toEqual(mock.cur_names[1].split(' ')[0] + ' has stopped typing');
|
||||||
|
}, converse));
|
||||||
|
|
||||||
|
}, converse));
|
||||||
|
|
||||||
|
describe("An gone notifciation", $.proxy(function () {
|
||||||
|
it("is sent if the user closes a chat box", $.proxy(function () {
|
||||||
|
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
test_utils.openChatBoxFor(contact_jid);
|
||||||
|
var view = this.chatboxviews.get(contact_jid);
|
||||||
|
expect(view.model.get('chat_state')).toBe('active');
|
||||||
|
spyOn(converse.connection, 'send');
|
||||||
|
view.close();
|
||||||
expect(view.model.get('chat_state')).toBe('gone');
|
expect(view.model.get('chat_state')).toBe('gone');
|
||||||
expect(converse.connection.send).toHaveBeenCalled();
|
expect(converse.connection.send).toHaveBeenCalled();
|
||||||
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
|
var $stanza = $(converse.connection.send.argsForCall[0][0].tree());
|
||||||
expect($stanza.attr('to')).toBe(contact_jid);
|
expect($stanza.attr('to')).toBe(contact_jid);
|
||||||
expect($stanza.children().length).toBe(1);
|
expect($stanza.children().length).toBe(1);
|
||||||
expect($stanza.children().prop('tagName')).toBe('gone');
|
expect($stanza.children().prop('tagName')).toBe('gone');
|
||||||
});
|
|
||||||
}, converse));
|
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
|
xit("will be shown if received", $.proxy(function () {
|
||||||
|
// TODO: only show paused state if the previous state was composing
|
||||||
|
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
|
||||||
|
spyOn(converse, 'emit');
|
||||||
|
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
|
// <paused> state
|
||||||
|
msg = $msg({
|
||||||
|
from: sender_jid,
|
||||||
|
to: this.connection.jid,
|
||||||
|
type: 'chat',
|
||||||
|
id: (new Date()).getTime()
|
||||||
|
}).c('body').c('gone', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||||
|
this.chatboxes.onMessage(msg);
|
||||||
|
expect(converse.emit).toHaveBeenCalledWith('message', msg);
|
||||||
|
var chatboxview = this.chatboxviews.get(sender_jid);
|
||||||
|
$events = chatboxview.$el.find('.chat-event');
|
||||||
|
expect($events.length).toBe(1);
|
||||||
|
expect($events.text()).toEqual(mock.cur_names[1].split(' ')[0] + ' has stopped typing');
|
||||||
|
}, converse));
|
||||||
|
}, converse));
|
||||||
}, converse));
|
}, converse));
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user