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_logout: true,
|
||||||
allow_muc: true,
|
allow_muc: true,
|
||||||
allow_otr: true,
|
allow_otr: true,
|
||||||
auto_away: 0, //in seconds
|
auto_away: 0, // Seconds after which user status is set to 'away'
|
||||||
auto_xa: 0, //in seconds
|
auto_xa: 0, // Seconds after which user status is set to 'xa'
|
||||||
allow_registration: true,
|
allow_registration: true,
|
||||||
animate: true,
|
animate: true,
|
||||||
auto_list_rooms: false,
|
auto_list_rooms: false,
|
||||||
@ -297,6 +297,7 @@
|
|||||||
auto_subscribe: false,
|
auto_subscribe: false,
|
||||||
bosh_service_url: undefined, // The BOSH connection manager URL.
|
bosh_service_url: undefined, // The BOSH connection manager URL.
|
||||||
cache_otr_key: false,
|
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,
|
debug: false,
|
||||||
domain_placeholder: __(" e.g. conversejs.org"), // Placeholder text shown in the domain input on the registration form
|
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.
|
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,
|
hide_offline_users: false,
|
||||||
jid: undefined,
|
jid: undefined,
|
||||||
keepalive: false,
|
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)
|
no_trimming: false, // Set to true for phantomjs tests (where browser apparently has no width)
|
||||||
ping_interval: 180, //in seconds
|
ping_interval: 180, //in seconds
|
||||||
play_sounds: false,
|
play_sounds: false,
|
||||||
@ -337,6 +338,8 @@
|
|||||||
xhr_user_search: false,
|
xhr_user_search: false,
|
||||||
xhr_user_search_url: ''
|
xhr_user_search_url: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
_.extend(this, this.default_settings);
|
_.extend(this, this.default_settings);
|
||||||
// Allow only whitelisted configuration attributes to be overwritten
|
// Allow only whitelisted configuration attributes to be overwritten
|
||||||
_.extend(this, _.pick(settings, Object.keys(this.default_settings)));
|
_.extend(this, _.pick(settings, Object.keys(this.default_settings)));
|
||||||
@ -415,54 +418,56 @@
|
|||||||
// ----------------------
|
// ----------------------
|
||||||
|
|
||||||
this.sendCSI = function (stat) {
|
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}));
|
converse.connection.send($build(stat, {xmlns: Strophe.NS.CSI}));
|
||||||
}
|
this.inactive = (stat === INACTIVE) ? true : false;
|
||||||
};
|
|
||||||
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.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 () {
|
this.playNotification = function () {
|
||||||
var audio;
|
var audio;
|
||||||
@ -842,7 +847,7 @@
|
|||||||
this.enableCarbons();
|
this.enableCarbons();
|
||||||
this.initStatus($.proxy(function () {
|
this.initStatus($.proxy(function () {
|
||||||
this.registerPingHandler();
|
this.registerPingHandler();
|
||||||
this.registerAutoAwayHandler();
|
this.registerIntervalHandler();
|
||||||
this.chatboxes.onConnected();
|
this.chatboxes.onConnected();
|
||||||
this.giveFeedback(__('Contacts'));
|
this.giveFeedback(__('Contacts'));
|
||||||
if (this.callback) {
|
if (this.callback) {
|
||||||
@ -1206,9 +1211,7 @@
|
|||||||
);
|
);
|
||||||
this.renderToolbar().renderAvatar();
|
this.renderToolbar().renderAvatar();
|
||||||
converse.emit('chatBoxOpened', this);
|
converse.emit('chatBoxOpened', this);
|
||||||
setTimeout(function () {
|
setTimeout(converse.refreshWebkit, 50);
|
||||||
converse.refreshWebkit();
|
|
||||||
}, 50);
|
|
||||||
return this.showStatusMessage();
|
return this.showStatusMessage();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2543,9 +2546,7 @@
|
|||||||
this.$el.attr('id', this.model.get('box_id'))
|
this.$el.attr('id', this.model.get('box_id'))
|
||||||
.html(converse.templates.chatroom(this.model.toJSON()));
|
.html(converse.templates.chatroom(this.model.toJSON()));
|
||||||
this.renderChatArea();
|
this.renderChatArea();
|
||||||
setTimeout(function () {
|
setTimeout(converse.refreshWebkit, 50);
|
||||||
converse.refreshWebkit();
|
|
||||||
}, 50);
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -5720,7 +5721,7 @@
|
|||||||
*/
|
*/
|
||||||
if (this.keepalive) {
|
if (this.keepalive) {
|
||||||
try {
|
try {
|
||||||
return this.connection.restore(null, this.onConnectStatusChanged);
|
return this.connection.restore(undefined, this.onConnectStatusChanged);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
converse.log("Could not restore sessions. Error message: "+e.message);
|
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.");
|
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) {
|
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) {
|
} else if (this.bosh_service_url) {
|
||||||
this.connection = new Strophe.Connection(this.bosh_service_url, {'keepalive': this.keepalive});
|
this.connection = new Strophe.Connection(this.bosh_service_url, {'keepalive': this.keepalive});
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,6 +23,7 @@ Changelog
|
|||||||
* Refactored in order to remove the strophe.roster.js dependency. [jcbrand]
|
* Refactored in order to remove the strophe.roster.js dependency. [jcbrand]
|
||||||
* Refactored the plugin architecture. Add `overrides` convention for
|
* Refactored the plugin architecture. Add `overrides` convention for
|
||||||
automatically overriding converse.js's methods and Backbone views and models. [jcbrand]
|
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)
|
0.9.3 (2015-05-01)
|
||||||
------------------
|
------------------
|
||||||
|
@ -180,21 +180,22 @@ auto_away
|
|||||||
|
|
||||||
* Default: ``0``
|
* 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 user's status is ``extended away``, it won't be changed to ``away``.
|
||||||
If the value if negative or ``0``, the function is disabled.
|
|
||||||
|
If the given value is negative or ``0``, this option is disabled.
|
||||||
|
|
||||||
auto_xa
|
auto_xa
|
||||||
-------
|
-------
|
||||||
|
|
||||||
* Default: ``0``
|
* 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)
|
If the value is negative or ``0``, the function is disabled.
|
||||||
The value must be greater than ``auto_away``
|
|
||||||
If the value if negative or ``0``, the function is disabled.
|
|
||||||
|
|
||||||
auto_reconnect
|
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
|
to retrieve your private key and read your all the chat messages in your
|
||||||
current session. Previous sessions however cannot be decrypted.
|
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
|
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 () {
|
describe("The \"tokens\" API", $.proxy(function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
test_utils.closeAllChatBoxes();
|
test_utils.closeAllChatBoxes();
|
||||||
|
Loading…
Reference in New Issue
Block a user