Decouple automatic away and XEP-0352 support.
- Add new config option csi_waiting_time for CSI support. - The auto_away and auto_xa options won't send out CSI stanzas if csi_waiting_time is 0 - Update docs and add tests for both features.
This commit is contained in:
parent
7551c629bd
commit
868435173f
113
converse.js
113
converse.js
@ -287,8 +287,8 @@
|
||||
allow_logout: true,
|
||||
allow_muc: true,
|
||||
allow_otr: true,
|
||||
auto_away: 0, //in seconds
|
||||
auto_xa: 0, //in seconds
|
||||
auto_away: 0, // Seconds after which user status is set to 'away'
|
||||
auto_xa: 0, // Seconds after which user status is set to 'xa'
|
||||
allow_registration: true,
|
||||
animate: true,
|
||||
auto_list_rooms: false,
|
||||
@ -297,6 +297,7 @@
|
||||
auto_subscribe: false,
|
||||
bosh_service_url: undefined, // The BOSH connection manager URL.
|
||||
cache_otr_key: false,
|
||||
csi_waiting_time: 0, // Support for XEP-0352. Seconds before client is considered idle and CSI is sent out.
|
||||
debug: false,
|
||||
domain_placeholder: __(" e.g. conversejs.org"), // Placeholder text shown in the domain input on the registration form
|
||||
default_box_height: 400, // The default height, in pixels, for the control box, chat boxes and chatrooms.
|
||||
@ -306,7 +307,7 @@
|
||||
hide_offline_users: false,
|
||||
jid: undefined,
|
||||
keepalive: false,
|
||||
message_carbons: false,
|
||||
message_carbons: false, // Support for XEP-280
|
||||
no_trimming: false, // Set to true for phantomjs tests (where browser apparently has no width)
|
||||
ping_interval: 180, //in seconds
|
||||
play_sounds: false,
|
||||
@ -337,6 +338,8 @@
|
||||
xhr_user_search: false,
|
||||
xhr_user_search_url: ''
|
||||
};
|
||||
|
||||
|
||||
_.extend(this, this.default_settings);
|
||||
// Allow only whitelisted configuration attributes to be overwritten
|
||||
_.extend(this, _.pick(settings, Object.keys(this.default_settings)));
|
||||
@ -415,54 +418,56 @@
|
||||
// ----------------------
|
||||
|
||||
this.sendCSI = function (stat) {
|
||||
if (converse.features[Strophe.NS.CSI]) {
|
||||
/* Send out a Chat Status Notification (XEP-0352) */
|
||||
if (converse.features[Strophe.NS.CSI] || true) {
|
||||
converse.connection.send($build(stat, {xmlns: Strophe.NS.CSI}));
|
||||
}
|
||||
};
|
||||
this.autoAwayReset = function () {
|
||||
if (converse._idleCounter > 0) {
|
||||
converse._idleCounter = 0;
|
||||
if (converse._autoAway > 0) {
|
||||
converse._autoAway = 0;
|
||||
converse.sendCSI(ACTIVE);
|
||||
converse.xmppstatus.setStatus('online');
|
||||
}
|
||||
}
|
||||
};
|
||||
this.registerAutoAwayHandler = function () {
|
||||
// TODO: we should probably come up with a way to decouple CSI and auto-away
|
||||
if (this.auto_away > 0 || this.auto_xa > 0) {
|
||||
if (this.auto_xa > 0 && this.auto_xa < this.auto_away) {
|
||||
this.auto_xa = this.auto_away;
|
||||
}
|
||||
this._idleCounter = 0;
|
||||
this._autoAway = 0;
|
||||
$(window).on('click' , function () { converse.autoAwayReset(); });
|
||||
$(window).on('mousemove' , function () { converse.autoAwayReset(); });
|
||||
$(window).on('keypress' , function () { converse.autoAwayReset(); });
|
||||
$(window).on('focus' , function () { converse.autoAwayReset(); });
|
||||
$(window).on(unloadevent , function () { converse.autoAwayReset(); });
|
||||
|
||||
window.setInterval(function () {
|
||||
if ((this._idleCounter <= this.auto_away || (this.auto_xa > 0 && this._idleCounter <= this.auto_xa)) &&
|
||||
(this.xmppstatus.get('status') == 'online' && this._autoAway === 0) || (this.xmppstatus.get('status') == 'away' && this._autoAway == 1) ){
|
||||
this._idleCounter++;
|
||||
}
|
||||
if (this.auto_away > 0 && this._autoAway != 1 && this._idleCounter > this.auto_away && this._idleCounter <= this.auto_xa){
|
||||
this.sendCSI(INACTIVE);
|
||||
this._autoAway = 1;
|
||||
this.xmppstatus.setStatus('away');
|
||||
}
|
||||
else if (this.auto_xa > 0 && this._autoAway != 2 && this._idleCounter > this.auto_xa){
|
||||
this.sendCSI(INACTIVE);
|
||||
this._autoAway = 2;
|
||||
this.xmppstatus.setStatus('xa');
|
||||
}
|
||||
}.bind(this), 1000); //every seconds
|
||||
return true;
|
||||
this.inactive = (stat === INACTIVE) ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
this.onUserActivity = function () {
|
||||
/* Reset counters and flags relating to user activity. */
|
||||
if (this.idle_seconds > 0) {
|
||||
this.idle_seconds = 0;
|
||||
}
|
||||
if (this.inactive) {
|
||||
this.sendCSI(ACTIVE);
|
||||
}
|
||||
if (this.auto_changed_status === true) {
|
||||
this.auto_changed_status = false;
|
||||
this.xmppstatus.setStatus('online');
|
||||
}
|
||||
};
|
||||
|
||||
this.onEverySecond = function () {
|
||||
/* An interval handler running every second */
|
||||
var stat = this.xmppstatus.getStatus();
|
||||
this.idle_seconds++;
|
||||
if (this.idle_seconds > this.csi_waiting_time && !this.inactive) {
|
||||
this.sendCSI(INACTIVE);
|
||||
}
|
||||
if (this.auto_away > 0 && this.idle_seconds > this.auto_away && stat !== 'away' && stat !== 'xa') {
|
||||
this.auto_changed_status = true;
|
||||
this.xmppstatus.setStatus('away');
|
||||
} else if (this.auto_xa > 0 && this.idle_seconds > this.auto_xa && stat !== 'xa') {
|
||||
this.auto_changed_status = true;
|
||||
this.xmppstatus.setStatus('xa');
|
||||
}
|
||||
};
|
||||
|
||||
this.registerIntervalHandler = function () {
|
||||
/* Set an interval of one second and register a handler for it.
|
||||
* Required for the auto_away, auto_xa and csi_waiting_time features.
|
||||
*/
|
||||
if (this.auto_away < 1 && this.auto_xa < 1 && this.csi_waiting_time < 1) {
|
||||
// Waiting time of less then one second means features aren't used.
|
||||
return;
|
||||
}
|
||||
this.idle_seconds = 0;
|
||||
this.auto_changed_status = false; // Was the user's status changed by converse.js?
|
||||
$(window).on('click mousemove keypress focus'+unloadevent , this.onUserActivity.bind(this));
|
||||
window.setInterval(this.onEverySecond.bind(this), 1000);
|
||||
};
|
||||
|
||||
this.playNotification = function () {
|
||||
var audio;
|
||||
@ -842,7 +847,7 @@
|
||||
this.enableCarbons();
|
||||
this.initStatus($.proxy(function () {
|
||||
this.registerPingHandler();
|
||||
this.registerAutoAwayHandler();
|
||||
this.registerIntervalHandler();
|
||||
this.chatboxes.onConnected();
|
||||
this.giveFeedback(__('Contacts'));
|
||||
if (this.callback) {
|
||||
@ -1206,9 +1211,7 @@
|
||||
);
|
||||
this.renderToolbar().renderAvatar();
|
||||
converse.emit('chatBoxOpened', this);
|
||||
setTimeout(function () {
|
||||
converse.refreshWebkit();
|
||||
}, 50);
|
||||
setTimeout(converse.refreshWebkit, 50);
|
||||
return this.showStatusMessage();
|
||||
},
|
||||
|
||||
@ -2543,9 +2546,7 @@
|
||||
this.$el.attr('id', this.model.get('box_id'))
|
||||
.html(converse.templates.chatroom(this.model.toJSON()));
|
||||
this.renderChatArea();
|
||||
setTimeout(function () {
|
||||
converse.refreshWebkit();
|
||||
}, 50);
|
||||
setTimeout(converse.refreshWebkit, 50);
|
||||
return this;
|
||||
},
|
||||
|
||||
@ -5720,7 +5721,7 @@
|
||||
*/
|
||||
if (this.keepalive) {
|
||||
try {
|
||||
return this.connection.restore(null, this.onConnectStatusChanged);
|
||||
return this.connection.restore(undefined, this.onConnectStatusChanged);
|
||||
} catch (e) {
|
||||
converse.log("Could not restore sessions. Error message: "+e.message);
|
||||
}
|
||||
@ -5749,7 +5750,7 @@
|
||||
throw new Error("initConnection: you must supply a value for either the bosh_service_url or websocket_url or both.");
|
||||
}
|
||||
if (('WebSocket' in window || 'MozWebSocket' in window) && this.websocket_url) {
|
||||
this.connection = new Strophe.Connection(this.websocket_url, {'keepalive': this.keepalive});
|
||||
this.connection = new Strophe.Connection(this.websocket_url);
|
||||
} else if (this.bosh_service_url) {
|
||||
this.connection = new Strophe.Connection(this.bosh_service_url, {'keepalive': this.keepalive});
|
||||
} else {
|
||||
|
@ -23,6 +23,7 @@ Changelog
|
||||
* Refactored in order to remove the strophe.roster.js dependency. [jcbrand]
|
||||
* Refactored the plugin architecture. Add `overrides` convention for
|
||||
automatically overriding converse.js's methods and Backbone views and models. [jcbrand]
|
||||
* Decouple automatic away and XEP-0352 support. [jcbrand]
|
||||
|
||||
0.9.3 (2015-05-01)
|
||||
------------------
|
||||
|
@ -180,21 +180,22 @@ auto_away
|
||||
|
||||
* Default: ``0``
|
||||
|
||||
This option can be used to let converse.js automatically change user presence
|
||||
The amount of seconds after which the user's presence status should
|
||||
automatically become ``away``.
|
||||
|
||||
This set the number a seconds before user presence become ``away``
|
||||
If the value if negative or ``0``, the function is disabled.
|
||||
If the user's status is ``extended away``, it won't be changed to ``away``.
|
||||
|
||||
If the given value is negative or ``0``, this option is disabled.
|
||||
|
||||
auto_xa
|
||||
-------
|
||||
|
||||
* Default: ``0``
|
||||
|
||||
This option can be used to let converse.js automatically change user presence
|
||||
The amount of seconds after which the user's presence status should
|
||||
automatically become ``extended away``.
|
||||
|
||||
This set the number a seconds before user presence become ``xa`` (eXtended Away)
|
||||
The value must be greater than ``auto_away``
|
||||
If the value if negative or ``0``, the function is disabled.
|
||||
If the value is negative or ``0``, the function is disabled.
|
||||
|
||||
auto_reconnect
|
||||
--------------
|
||||
@ -253,6 +254,20 @@ This setting can only be used together with ``allow_otr = true``.
|
||||
to retrieve your private key and read your all the chat messages in your
|
||||
current session. Previous sessions however cannot be decrypted.
|
||||
|
||||
csi_waiting_time
|
||||
----------------
|
||||
|
||||
* Default: ``0``
|
||||
|
||||
This option adds support for **XEP-0085 Chat State Indication**.
|
||||
|
||||
If converse.js is idle for the configured amount of seconds, a chat state
|
||||
indication of ``inactive`` will be sent out to the XMPP server (if the server
|
||||
supports CSI).
|
||||
|
||||
Afterwards, ss soon as there is any activity (for example, the mouse moves),
|
||||
a chat state indication of ``active`` will be sent out.
|
||||
|
||||
debug
|
||||
-----
|
||||
|
||||
|
@ -57,6 +57,79 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe("A chat state indication", function () {
|
||||
|
||||
it("are sent out when the client becomes or stops being idle", function () {
|
||||
spyOn(converse, 'sendCSI').andCallThrough();
|
||||
var sent_stanza;
|
||||
spyOn(converse.connection, 'send').andCallFake(function (stanza) {
|
||||
sent_stanza = stanza;
|
||||
});
|
||||
var i = 0;
|
||||
converse.idle_seconds = 0; // Usually initialized by registerIntervalHandler
|
||||
converse.features['urn:xmpp:csi:0'] = true; // Mock that the server supports CSI
|
||||
|
||||
converse.csi_waiting_time = 3; // The relevant config option
|
||||
while (i <= converse.csi_waiting_time) {
|
||||
expect(converse.sendCSI).not.toHaveBeenCalled();
|
||||
converse.onEverySecond();
|
||||
i++;
|
||||
}
|
||||
expect(converse.sendCSI).toHaveBeenCalledWith('inactive');
|
||||
expect(sent_stanza.toLocaleString()).toBe(
|
||||
"<inactive xmlns='urn:xmpp:csi:0'/>"
|
||||
);
|
||||
converse.onUserActivity();
|
||||
expect(converse.sendCSI).toHaveBeenCalledWith('active');
|
||||
expect(sent_stanza.toLocaleString()).toBe(
|
||||
"<active xmlns='urn:xmpp:csi:0'/>"
|
||||
);
|
||||
|
||||
// Reset values
|
||||
converse.csi_waiting_time = 0;
|
||||
converse.features['urn:xmpp:csi:0'] = false;
|
||||
});
|
||||
});
|
||||
|
||||
describe("Automatic status change", function () {
|
||||
|
||||
it("happens when the client is idle for long enough", function () {
|
||||
var i = 0;
|
||||
// Usually initialized by registerIntervalHandler
|
||||
converse.idle_seconds = 0;
|
||||
converse.auto_changed_status = false;
|
||||
|
||||
// The relevant config options
|
||||
converse.auto_away = 3;
|
||||
converse.auto_xa = 6;
|
||||
|
||||
expect(converse.xmppstatus.getStatus()).toBe('online');
|
||||
|
||||
while (i <= converse.auto_away) {
|
||||
converse.onEverySecond();
|
||||
i++;
|
||||
}
|
||||
expect(converse.auto_changed_status).toBe(true);
|
||||
|
||||
while (i <= converse.auto_xa) {
|
||||
expect(converse.xmppstatus.getStatus()).toBe('away');
|
||||
converse.onEverySecond();
|
||||
i++;
|
||||
}
|
||||
expect(converse.xmppstatus.getStatus()).toBe('xa');
|
||||
expect(converse.auto_changed_status).toBe(true);
|
||||
|
||||
converse.onUserActivity();
|
||||
expect(converse.xmppstatus.getStatus()).toBe('online');
|
||||
expect(converse.auto_changed_status).toBe(false);
|
||||
|
||||
// Reset values
|
||||
converse.auto_away = 0;
|
||||
converse.auto_xa = 0;
|
||||
converse.auto_changed_status = false;
|
||||
});
|
||||
});
|
||||
|
||||
describe("The \"tokens\" API", $.proxy(function () {
|
||||
beforeEach(function () {
|
||||
test_utils.closeAllChatBoxes();
|
||||
|
Loading…
Reference in New Issue
Block a user