Commit b47069b4 authored by JC Brand's avatar JC Brand

Add, test and document an API method for setting the user's status.

fixes #367
parent f5c73cfe
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
bourbon (4.2.3)
sass (~> 3.4)
thor
sass (3.4.14) sass (3.4.14)
thor (0.19.1)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
bourbon
sass (~> 3.3) sass (~> 3.3)
BUNDLED WITH BUNDLED WITH
......
...@@ -139,6 +139,16 @@ ...@@ -139,6 +139,16 @@
} }
}; };
var STATUS_WEIGHTS = {
'offline': 6,
'unavailable': 5,
'xa': 4,
'away': 3,
'dnd': 2,
'chat': 1, // We currently don't differentiate between "chat" and "online"
'online': 1
};
converse.initialize = function (settings, callback) { converse.initialize = function (settings, callback) {
"use strict"; "use strict";
var converse = this; var converse = this;
...@@ -195,14 +205,6 @@ ...@@ -195,14 +205,6 @@
ENTER: 13, ENTER: 13,
FORWARD_SLASH: 47 FORWARD_SLASH: 47
}; };
var STATUS_WEIGHTS = {
'offline': 6,
'unavailable': 5,
'xa': 4,
'away': 3,
'dnd': 2,
'online': 1
};
var PRETTY_CONNECTION_STATUS = { var PRETTY_CONNECTION_STATUS = {
0: 'ERROR', 0: 'ERROR',
...@@ -4241,8 +4243,9 @@ ...@@ -4241,8 +4243,9 @@
contact = this.get(bare_jid); contact = this.get(bare_jid);
if (this.isSelf(bare_jid)) { if (this.isSelf(bare_jid)) {
if ((converse.connection.jid !== jid)&&(presence_type !== 'unavailable')) { if ((converse.connection.jid !== jid)&&(presence_type !== 'unavailable')) {
// Another resource has changed it's status, we'll update ours as well. // Another resource has changed its status, we'll update ours as well.
converse.xmppstatus.save({'status': chat_status}); converse.xmppstatus.save({'status': chat_status});
if (status_message.length) { converse.xmppstatus.save({'status_message': status_message}); }
} }
return; return;
} else if (($presence.find('x').attr('xmlns') || '').indexOf(Strophe.NS.MUC) === 0) { } else if (($presence.find('x').attr('xmlns') || '').indexOf(Strophe.NS.MUC) === 0) {
...@@ -5938,9 +5941,38 @@ ...@@ -5938,9 +5941,38 @@
converse.connection.disconnect(); converse.connection.disconnect();
}, },
'account': { 'account': {
// XXX: Deprecated, will be removed with next non-minor release
'logout': function () {
converse.logOut();
}
},
'user': {
'logout': function () { 'logout': function () {
converse.logOut(); converse.logOut();
}, },
'status': {
'get': function () {
return converse.xmppstatus.get('status');
},
'set': function (value, message) {
var data = {'status': value};
if (!_.contains(_.keys(STATUS_WEIGHTS), value)) {
throw new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1');
}
if (typeof message == "string") {
data.status_message = message;
}
converse.xmppstatus.save(data);
},
'message': {
'get': function () {
return converse.xmppstatus.get('status_message');
},
'set': function (stat) {
converse.xmppstatus.save({'status_message': stat});
}
}
},
}, },
'settings': { 'settings': {
'get': function (key) { 'get': function (key) {
......
...@@ -223,6 +223,8 @@ ...@@ -223,6 +223,8 @@
content: "\e01f"; } content: "\e01f"; }
#conversejs .icon-online:before { #conversejs .icon-online:before {
content: "\25fc"; } content: "\25fc"; }
#conversejs .icon-chat:before {
content: "\25fc"; }
#conversejs .icon-opened:before { #conversejs .icon-opened:before {
content: "\25bc"; } content: "\25bc"; }
#conversejs .icon-pencil:before { #conversejs .icon-pencil:before {
......
...@@ -4,7 +4,8 @@ Changelog ...@@ -4,7 +4,8 @@ Changelog
0.9.4 (Unreleased) 0.9.4 (Unreleased)
------------------ ------------------
* #144 Add Ping funcionnality and Pong Handler [thierrytiti] * #144 Add Ping functionality and Pong handler [thierrytiti]
* #367 API methods for changing chat status (online, busy, away etc.) and status message [jcbrand]
* #389 Allow login panel placeholders and roster item 'Name' translations. [gbonvehi] * #389 Allow login panel placeholders and roster item 'Name' translations. [gbonvehi]
* #394 Option to allow chatting with pending contacts [thierrytiti] * #394 Option to allow chatting with pending contacts [thierrytiti]
* #396 Add automatic Away mode and XEP-0352 support [thierrytiti] * #396 Add automatic Away mode and XEP-0352 support [thierrytiti]
...@@ -31,7 +32,7 @@ Changelog ...@@ -31,7 +32,7 @@ Changelog
* CSS: Fonts Path: editabable $font-path via sass/variables.scss [thierrytiti] * CSS: Fonts Path: editabable $font-path via sass/variables.scss [thierrytiti]
* Add offline pretty status to enable translation [thierrytiti] * Add offline pretty status to enable translation [thierrytiti]
* With keepalive, don't send out a presence stanza on each page load [jcbrand] * With keepalive, don't send out a presence stanza on each page load [jcbrand]
* Chat boxes returned by the API now have an ``is_chatroom`` attribute [jcbrand] * Chat boxes returned by the API now have an `is_chatroom` attribute [jcbrand]
0.9.3 (2015-05-01) 0.9.3 (2015-05-01)
------------------ ------------------
......
...@@ -6,6 +6,15 @@ h1 { ...@@ -6,6 +6,15 @@ h1 {
font-size: 50px; font-size: 50px;
} }
h4 {
font-weight: bold;
}
h5 {
font-size: 16px;
font-weight: bold;
}
.navbar-brand { .navbar-brand {
padding-top: 7px; padding-top: 7px;
} }
......
...@@ -203,9 +203,77 @@ Example: ...@@ -203,9 +203,77 @@ Example:
}); });
"contacts" grouping The "user" grouping
------------------- -------------------
This grouping collects API functions related to the current logged in user.
logout
~~~~~~
Log the user out of the current XMPP session.
.. code-block:: javascript
converse.user.logout();
The "status" sub-grouping
~~~~~~~~~~~~~~~~~~~~~~~~~
Set and get the user's chat status, also called their *availability*.
get
^^^
Return the current user's availability status:
.. code-block:: javascript
converse.user.status.get(); // Returns for example "dnd"
set
^^^
The user's status can be set to one of the following values:
* **away**
* **dnd**
* **offline**
* **online**
* **unavailable**
* **xa**
For example:
.. code-block:: javascript
converse.user.status.set('dnd');
Because the user's availability is often set together with a custom status
message, this method also allows you to pass in a status message as a
second parameter:
.. code-block:: javascript
converse.user.status.set('dnd', 'In a meeting');
The "message" sub-grouping
^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``user.status.message`` sub-grouping exposes methods for setting and
retrieving the user's custom status message.
.. code-block:: javascript
converse.user.status.message.set('In a meeting');
converse.user.status.message.get(); // Returns "In a meeting"
The "contacts" grouping
-----------------------
get get
~~~ ~~~
...@@ -213,68 +281,78 @@ This method is used to retrieve roster contacts. ...@@ -213,68 +281,78 @@ This method is used to retrieve roster contacts.
To get a single roster contact, call the method with the contact's JID (Jabber ID): To get a single roster contact, call the method with the contact's JID (Jabber ID):
.. code-block:: javascript
converse.contacts.get('buddy@example.com') converse.contacts.get('buddy@example.com')
To get multiple contacts, pass in an array of JIDs:: To get multiple contacts, pass in an array of JIDs:
.. code-block:: javascript
converse.contacts.get(['buddy1@example.com', 'buddy2@example.com']) converse.contacts.get(['buddy1@example.com', 'buddy2@example.com'])
To return all contacts, simply call ``get`` without any parameters:: To return all contacts, simply call ``get`` without any parameters:
.. code-block:: javascript
converse.contacts.get() converse.contacts.get()
The returned roster contact objects have these attributes: The returned roster contact objects have these attributes:
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| Attribute | | | Attribute | |
+================+======================================================================================================================================+ +================+=================================================================================================================+
| ask | If ask === 'subscribe', then we have asked this person to be our chat buddy. | | ask | If ask === 'subscribe', then we have asked this person to be our chat buddy. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| fullname | The person's full name. | | fullname | The person's full name. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| jid | The person's Jabber/XMPP username. | | jid | The person's Jabber/XMPP username. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| requesting | If true, then this person is asking to be our chat buddy. | | requesting | If true, then this person is asking to be our chat buddy. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| subscription | The subscription state between the current user and this chat buddy. Can be `none`, `to`, `from` or `both`. | | subscription | The subscription state between the current user and this chat buddy. Can be `none`, `to`, `from` or `both`. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| id | A unique id, same as the jid. | | id | A unique id, same as the jid. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| chat_status | The person's chat status. Can be `online`, `offline`, `busy`, `xa` (extended away) or `away`. | | chat_status | The person's chat status. Can be `online`, `offline`, `busy`, `xa` (extended away) or `away`. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| user_id | The user id part of the JID (the part before the `@`). | | user_id | The user id part of the JID (the part before the `@`). |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| resources | The known resources for this chat buddy. Each resource denotes a separate and connected chat client. | | resources | The known resources for this chat buddy. Each resource denotes a separate and connected chat client. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| groups | The roster groups in which this chat buddy was placed. | | groups | The roster groups in which this chat buddy was placed. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| status | Their human readable custom status message. | | status | Their human readable custom status message. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| image_type | The image's file type. | | image_type | The image's file type. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| image | The Base64 encoded image data. | | image | The Base64 encoded image data. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| url | The buddy's website URL, as specified in their VCard data. | | url | The buddy's website URL, as specified in their VCard data. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
| vcard_updated | When last the buddy's VCard was updated. | | vcard_updated | When last the buddy's VCard was updated. |
+----------------+--------------------------------------------------------------------------------------------------------------------------------------+ +----------------+-----------------------------------------------------------------------------------------------------------------+
add add
~~~ ~~~
Add a contact. Add a contact.
Provide the JID of the contact you want to add:: Provide the JID of the contact you want to add:
.. code-block:: javascript
converse.contacts.add('buddy@example.com') converse.contacts.add('buddy@example.com')
You may also provide the fullname. If not present, we use the jid as fullname:: You may also provide the fullname. If not present, we use the jid as fullname:
.. code-block:: javascript
converse.contacts.add('buddy@example.com', 'Buddy') converse.contacts.add('buddy@example.com', 'Buddy')
"chats" grouping The "chats" grouping
---------------- --------------------
get get
~~~ ~~~
...@@ -282,11 +360,15 @@ get ...@@ -282,11 +360,15 @@ get
Returns an object representing a chat box. Returns an object representing a chat box.
To return a single chat box, provide the JID of the contact you're chatting To return a single chat box, provide the JID of the contact you're chatting
with in that chat box:: with in that chat box:
.. code-block:: javascript
converse.chats.get('buddy@example.com') converse.chats.get('buddy@example.com')
To return an array of chat boxes, provide an array of JIDs:: To return an array of chat boxes, provide an array of JIDs:
.. code-block:: javascript
converse.chats.get(['buddy1@example.com', 'buddy2@example.com']) converse.chats.get(['buddy1@example.com', 'buddy2@example.com'])
...@@ -299,11 +381,15 @@ open ...@@ -299,11 +381,15 @@ open
Opens a chat box and returns an object representing a chat box. Opens a chat box and returns an object representing a chat box.
To open a single chat box, provide the JID of the contact:: To open a single chat box, provide the JID of the contact:
.. code-block:: javascript
converse.chats.open('buddy@example.com') converse.chats.open('buddy@example.com')
To return an array of chat boxes, provide an array of JIDs:: To return an array of chat boxes, provide an array of JIDs:
.. code-block:: javascript
converse.chats.open(['buddy1@example.com', 'buddy2@example.com']) converse.chats.open(['buddy1@example.com', 'buddy2@example.com'])
...@@ -340,8 +426,8 @@ To return an array of chat boxes, provide an array of JIDs:: ...@@ -340,8 +426,8 @@ To return an array of chat boxes, provide an array of JIDs::
| url | The URL of the chat box heading. | | url | The URL of the chat box heading. |
+-------------+-----------------------------------------------------+ +-------------+-----------------------------------------------------+
"rooms" grouping The "rooms" grouping
---------------- --------------------
get get
~~~ ~~~
...@@ -356,39 +442,51 @@ open ...@@ -356,39 +442,51 @@ open
Opens a multi user chat box and returns an object representing it. Opens a multi user chat box and returns an object representing it.
Similar to chats.get API Similar to chats.get API
To open a single multi user chat box, provide the JID of the room:: To open a single multi user chat box, provide the JID of the room:
.. code-block:: javascript
converse.rooms.open('group@muc.example.com') converse.rooms.open('group@muc.example.com')
To return an array of rooms, provide an array of room JIDs:: To return an array of rooms, provide an array of room JIDs:
.. code-block:: javascript
converse.rooms.open(['group1@muc.example.com', 'group2@muc.example.com']) converse.rooms.open(['group1@muc.example.com', 'group2@muc.example.com'])
To setup a custom nickname when joining the room, provide the optional nick argument:: To setup a custom nickname when joining the room, provide the optional nick argument:
.. code-block:: javascript
converse.rooms.open('group@muc.example.com', 'mycustomnick') converse.rooms.open('group@muc.example.com', 'mycustomnick')
"settings" grouping The "settings" grouping
------------------- -----------------------
This grouping allows you to get or set the configuration settings of converse.js. This grouping allows you to get or set the configuration settings of converse.js.
get(key) get(key)
~~~~~~~~ ~~~~~~~~
Returns the value of a configuration settings. For example:: Returns the value of a configuration settings. For example:
.. code-block:: javascript
converse.settings.get("play_sounds"); // default value returned would be false; converse.settings.get("play_sounds"); // default value returned would be false;
set(key, value) or set(object) set(key, value) or set(object)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Set one or many configuration settings. For example:: Set one or many configuration settings. For example:
.. code-block:: javascript
converse.settings.set("play_sounds", true); converse.settings.set("play_sounds", true);
or :: or :
.. code-block:: javascript
converse.settings.set({ converse.settings.set({
"play_sounds", true, "play_sounds", true,
...@@ -399,20 +497,22 @@ Note, this is not an alternative to calling ``converse.initialize``, which still ...@@ -399,20 +497,22 @@ Note, this is not an alternative to calling ``converse.initialize``, which still
to be called. Generally, you'd use this method after converse.js is already to be called. Generally, you'd use this method after converse.js is already
running and you want to change the configuration on-the-fly. running and you want to change the configuration on-the-fly.
"tokens" grouping The "tokens" grouping
----------------- ---------------------
get get
~~~ ~~~
Returns a token, either the RID or SID token depending on what's asked for. Returns a token, either the RID or SID token depending on what's asked for.
Example:: Example:
.. code-block:: javascript
converse.tokens.get('rid') converse.tokens.get('rid')
"listen" grouping The "listen" grouping
----------------- ---------------------
Converse.js emits events to which you can subscribe from your own Javascript. Converse.js emits events to which you can subscribe from your own Javascript.
...@@ -430,7 +530,9 @@ grouping: ...@@ -430,7 +530,9 @@ grouping:
* ``eventName`` is the event name as a string. * ``eventName`` is the event name as a string.
* ``callback`` is the callback method to be called when the event is emitted. * ``callback`` is the callback method to be called when the event is emitted.
For example:: For example:
.. code-block:: javascript
converse.listen.on('message', function (event, messageXML) { ... }); converse.listen.on('message', function (event, messageXML) { ... });
...@@ -444,7 +546,9 @@ grouping: ...@@ -444,7 +546,9 @@ grouping:
* ``eventName`` is the event name as a string. * ``eventName`` is the event name as a string.
* ``callback`` is the callback method to be called when the event is emitted. * ``callback`` is the callback method to be called when the event is emitted.
For example:: For example:
.. code-block:: javascript
converse.listen.once('message', function (event, messageXML) { ... }); converse.listen.once('message', function (event, messageXML) { ... });
...@@ -457,7 +561,9 @@ grouping: ...@@ -457,7 +561,9 @@ grouping:
* ``eventName`` is the event name as a string. * ``eventName`` is the event name as a string.
* ``callback`` refers to the function that is to be no longer executed. * ``callback`` refers to the function that is to be no longer executed.
For example:: For example:
.. code-block:: javascript
converse.listen.not('message', function (event, messageXML) { ... }); converse.listen.not('message', function (event, messageXML) { ... });
......
...@@ -192,6 +192,7 @@ ...@@ -192,6 +192,7 @@
.icon-notebook:before { content: "\2710"; } .icon-notebook:before { content: "\2710"; }
.icon-notification:before { content: "\e01f"; } .icon-notification:before { content: "\e01f"; }
.icon-online:before { content: "\25fc"; } .icon-online:before { content: "\25fc"; }
.icon-chat:before { content: "\25fc"; }
.icon-opened:before { content: "\25bc"; } .icon-opened:before { content: "\25bc"; }
.icon-pencil:before { content: "\270e"; } .icon-pencil:before { content: "\270e"; }
.icon-phone-hang-up:before { content: "\260e"; } .icon-phone-hang-up:before { content: "\260e"; }
......
...@@ -130,6 +130,57 @@ ...@@ -130,6 +130,57 @@
}); });
}); });
describe("The \"user\" grouping", function () {
describe("The \"status\" API", function () {
beforeEach(function () {
test_utils.closeAllChatBoxes();
test_utils.clearBrowserStorage();
converse.rosterview.model.reset();
});
it("has a method for getting the user's availability", function () {
converse.xmppstatus.set('status', 'online');
expect(converse_api.user.status.get()).toBe('online');
converse.xmppstatus.set('status', 'dnd');
expect(converse_api.user.status.get()).toBe('dnd');
});
it("has a method for setting the user's availability", function () {
converse_api.user.status.set('away');
expect(converse.xmppstatus.get('status')).toBe('away');
converse_api.user.status.set('dnd');
expect(converse.xmppstatus.get('status')).toBe('dnd');
converse_api.user.status.set('xa');
expect(converse.xmppstatus.get('status')).toBe('xa');
converse_api.user.status.set('chat');
expect(converse.xmppstatus.get('status')).toBe('chat');
expect(_.partial(converse_api.user.status.set, 'invalid')).toThrow(
new Error('Invalid availability value. See https://xmpp.org/rfcs/rfc3921.html#rfc.section.2.2.2.1')
);
});
it("allows setting the status message as well", function () {
converse_api.user.status.set('away', "I'm in a meeting");
expect(converse.xmppstatus.get('status')).toBe('away');
expect(converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
});
it("has a method for getting the user's status message", function () {
converse.xmppstatus.set('status_message', undefined);
expect(converse_api.user.status.message.get()).toBe(undefined);
converse.xmppstatus.set('status_message', "I'm in a meeting");
expect(converse_api.user.status.message.get()).toBe("I'm in a meeting");
});
it("has a method for setting the user's status message", function () {
converse.xmppstatus.set('status_message', undefined);
converse_api.user.status.message.set("I'm in a meeting");
expect(converse.xmppstatus.get('status_message')).toBe("I'm in a meeting");
});
});
});
describe("The \"tokens\" API", $.proxy(function () { describe("The \"tokens\" API", $.proxy(function () {
beforeEach(function () { beforeEach(function () {
test_utils.closeAllChatBoxes(); test_utils.closeAllChatBoxes();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment