Merge branch 'master' into gh-pages

This commit is contained in:
JC Brand 2013-04-25 00:24:29 +02:00
commit 093a7ecc4f
5 changed files with 101 additions and 75 deletions

View File

@ -12,6 +12,8 @@ Changelog
- Fixed user status handling, which wasn't 100% according to the - Fixed user status handling, which wasn't 100% according to the
spec. [jcbrand] spec. [jcbrand]
- Separate messages according to day in chats. [jcbrand] - Separate messages according to day in chats. [jcbrand]
- Add support for specifying the BOSH bind URL as configuration setting.
[jcbrand]
0.2 (2013-03-28) 0.2 (2013-03-28)

View File

@ -1864,27 +1864,35 @@
'<li><a class="current" href="#login">Sign in</a></li>'), '<li><a class="current" href="#login">Sign in</a></li>'),
template: _.template( template: _.template(
'<form id="converse-login">' + '<form id="converse-login">' +
'<label>XMPP ID:</label>' + '<label>XMPP/Jabber Username:</label>' +
'<input type="text" id="jid">' + '<input type="text" id="jid">' +
'<label>Password:</label>' + '<label>Password:</label>' +
'<input type="password" id="password">' + '<input type="password" id="password">' +
'<label>BOSH Service URL:</label>' +
'<input type="text" id="bosh_service_url">' +
'<input type="submit" name="submit"/>' + '<input type="submit" name="submit"/>' +
'</form">'), '</form">'),
authenticate: function (ev) { bosh_url_input: _.template(
'<label>BOSH Service URL:</label>' +
'<input type="text" id="bosh_service_url">'),
authenticate: $.proxy(function (ev) {
ev.preventDefault(); ev.preventDefault();
var $form = $(ev.target), var $form = $(ev.target),
$bsu_input = $form.find('input#bosh_service_url'),
bosh_service_url = $bsu_input.val(),
$jid_input = $form.find('input#jid'), $jid_input = $form.find('input#jid'),
jid = $jid_input.val(), jid = $jid_input.val(),
$pw_input = $form.find('input#password'), $pw_input = $form.find('input#password'),
password = $pw_input.val(), password = $pw_input.val(),
connection = new Strophe.Connection(bosh_service_url); $bsu_input = null,
errors = false;
var errors = false; if (! this.bosh_service_url) {
$bsu_input = $form.find('input#bosh_service_url');
this.bosh_service_url = $bsu_input.val();
if (! this.bosh_service_url) {
errors = true;
$bsu_input.addClass('error');
}
}
if (! jid) { if (! jid) {
errors = true; errors = true;
$jid_input.addClass('error'); $jid_input.addClass('error');
@ -1893,43 +1901,38 @@
errors = true; errors = true;
$pw_input.addClass('error'); $pw_input.addClass('error');
} }
if (! bosh_service_url) {
errors = true;
$bsu_input.addClass('error');
}
if (errors) { return; } if (errors) { return; }
// Clear the form's fields, so that it can't be submitted twice // Clear the form's fields, so that it can't be submitted twice
if ($bsu_input) {
$bsu_input.val(''); $bsu_input.val('');
}
$jid_input.val(''); $jid_input.val('');
$pw_input.val(''); $pw_input.val('');
var connection = new Strophe.Connection(this.bosh_service_url);
connection.connect(jid, password, $.proxy(function (status) { connection.connect(jid, password, $.proxy(function (status) {
if (status === Strophe.Status.CONNECTED) { if (status === Strophe.Status.CONNECTED) {
console.log('Connected'); console.log('Connected');
converse.onConnected(connection); this.onConnected(connection);
} else if (status === Strophe.Status.DISCONNECTED) { } else if (status === Strophe.Status.DISCONNECTED) {
console.log('Disconnected'); this.giveFeedback('Disconnected').css('background-image', "url(images/error_icon.png)");
this.$feedback.text('Unable to communicate with chat server').css('background-image', "url(images/error_icon.png)");
} else if (status === Strophe.Status.Error) { } else if (status === Strophe.Status.Error) {
console.log('Error'); this.giveFeedback('Error');
} else if (status === Strophe.Status.CONNECTING) { } else if (status === Strophe.Status.CONNECTING) {
console.log('Connecting'); this.giveFeedback('Connecting');
this.$feedback.text('Connecting to chat...');
} else if (status === Strophe.Status.CONNFAIL) { } else if (status === Strophe.Status.CONNFAIL) {
console.log('Connection Failed'); this.giveFeedback('Connection Failed');
} else if (status === Strophe.Status.AUTHENTICATING) { } else if (status === Strophe.Status.AUTHENTICATING) {
console.log('Authenticating'); this.giveFeedback('Authenticating');
converse.giveFeedback('Authenticating');
} else if (status === Strophe.Status.AUTHFAIL) { } else if (status === Strophe.Status.AUTHFAIL) {
console.log('Authenticating Failed'); this.giveFeedback('Authentication Failed');
converse.giveFeedback('Authentication failed');
} else if (status === Strophe.Status.DISCONNECTING) { } else if (status === Strophe.Status.DISCONNECTING) {
console.log('Disconnecting'); this.giveFeedback('Disconnecting');
} else if (status === Strophe.Status.ATTACHED) { } else if (status === Strophe.Status.ATTACHED) {
console.log('Attached'); console.log('Attached');
} }
}, this)); }, converse));
}, }, converse),
remove: function () { remove: function () {
this.$parent.find('#controlbox-tabs').empty(); this.$parent.find('#controlbox-tabs').empty();
@ -1938,7 +1941,11 @@
render: function () { render: function () {
this.$parent.find('#controlbox-tabs').append(this.tab_template()); this.$parent.find('#controlbox-tabs').append(this.tab_template());
this.$parent.find('#controlbox-panes').append(this.$el.html(this.template())); template = this.template();
if (! this.bosh_url_input) {
template.find('form').append(this.bosh_url_input);
}
this.$parent.find('#controlbox-panes').append(this.$el.html(template));
return this; return this;
} }
}); });
@ -1973,7 +1980,7 @@
}; };
converse.giveFeedback = function (message) { converse.giveFeedback = function (message) {
$('.conn-feedback').text(message); return $('.conn-feedback').text(message);
} }
converse.onConnected = function (connection) { converse.onConnected = function (connection) {
@ -2028,12 +2035,7 @@
}; };
converse.initialize = function (settings) { converse.initialize = function (settings) {
this.prebind = settings.prebind; _.extend(this, settings);
this.fullname = settings.fullname;
this.xhr_user_search = settings.xhr_user_search;
this.auto_subscribe = settings.auto_subscribe;
this.animate = settings.animate;
this.chatboxes = new this.ChatBoxes(); this.chatboxes = new this.ChatBoxes();
this.chatboxesview = new this.ChatBoxesView({model: this.chatboxes}); this.chatboxesview = new this.ChatBoxesView({model: this.chatboxes});
$('a.toggle-online-users').bind( $('a.toggle-online-users').bind(

View File

@ -9,14 +9,14 @@ Converse.js configuration variables:
Prebind Prebind
======== ========
Use this option if you don't want to render the login form on the chat control Use this option when you want to attach to an existing XMPP connection that was
box. already authenticated (usually on the backend before page load).
When set to true, the onConnected method needs to be called manually, together This is useful when you don't want to render the login form on the chat control
with a Strophe connection object. box with each page load.
The most likely usecase is if you want to already authenticate on the backend When set to true, you'll need to make sure that the onConnected method is
and merely attach to that connection in the browser. called, and passed to it a Strophe connection object.
Besides requiring the back-end to authenticate you, you'll also Besides requiring the back-end to authenticate you, you'll also
have to write a Javascript snippet to attach to the set up connection:: have to write a Javascript snippet to attach to the set up connection::
@ -24,16 +24,28 @@ have to write a Javascript snippet to attach to the set up connection::
$.JSON({ $.JSON({
'url': 'mysite.com/xmpp-authenticate', 'url': 'mysite.com/xmpp-authenticate',
'success': function (data) { 'success': function (data) {
connection = new Strophe.Connection(data.BOSH_SERVICE_URL); connection = new Strophe.Connection(bosh_service_url);
connection.attach(data.jid, data.sid, data.rid, converse.onConnected); connection.attach(data.jid, data.sid, data.rid, converse.onConnected);
} }
The backend must authenticate for you, and then return a SID (session ID) and
RID (Request ID), which you use when you attach to the connection.
fullname fullname
======== ========
If you are using prebinding, you need to specify the fullname of the currently If you are using prebinding, you need to specify the fullname of the currently
logged in user. logged in user.
bosh_service_url
================
Connections to an XMPP server depend on a BOSH connection manager which acts as
a middle man between HTTP and XMPP.
See `here`_ for more information.
xhr_user_search xhr_user_search
=============== ===============
@ -55,3 +67,7 @@ animate
======= =======
Show animations, for example when opening and closing chat boxes. Show animations, for example when opening and closing chat boxes.
.. _`here`: http://metajack.im/2008/09/08/which-bosh-server-do-you-need/l

View File

@ -29,24 +29,41 @@
<!-- MAIN CONTENT --> <!-- MAIN CONTENT -->
<div id="main_content_wrap" class="outer"> <div id="main_content_wrap" class="outer">
<section id="main_content" class="inner"> <section id="main_content" class="inner">
<p><strong>Converse.js</strong> is a web based <a href="http://xmpp.org" target="_blank">XMPP/Jabber</a> instant messaging client.</p> <p><strong>Converse.js</strong> is an open source, web based, <a href="http://xmpp.org" target="_blank">XMPP/Jabber</a> chat client, similar to
<p>It is used by <a href="http://github.com/collective/collective.xmpp.chat" target="_blank">collective.xmpp.chat</a>, which is a <a href="http://plone.org" target="_blank">Plone</a> instant messaging add-on.</p> <a href="https://www.facebook.com/sitetour/chat.php" target="_blank">Facebook chat</a>, except for the added support of multi-user chatrooms.</p>
<p>The ultimate goal is to enable anyone to add chat functionality to their websites, independent of any backend.
You will however need an XMPP server to connect to, either your own, or a public one.</p> <p>It is a Javascript application that you can include in your
website, thereby providing it with instant messaging functionality.</p>
<p>You will however need access to an XMPP/Jabber server.</p>
<p>You can connect to any public, federated XMPP server, or you could set one up
yourself, thereby maintaining stricter control of the user data (XMPP servers
usually don't archive chat messages).</p>
<h2>Features</h2> <h2>Features</h2>
<ul> <ul>
<li>Manually or automically subscribe to other users.</li> <li>Single and multi-user chat</li>
<li>Contact rosters</li>
<li>Manually or automically subscribe to other contacts</li>
<li>Roster item exchange (<a href="http://xmpp.org/extensions/tmp/xep-0144-1.1.html">XEP 144</a>)</li>
<li>Accept or decline contact requests</li> <li>Accept or decline contact requests</li>
<li>Chat statuses (online, busy, away, offline)</li> <li>Chat statuses (online, busy, away, offline)</li>
<li>Custom status messages</li> <li>Custom status messages</li>
<li>Typing notifications</li> <li>Typing notifications</li>
<li>Third person messages (/me )</li> <li>Third person messages (/me )</li>
<li>Multi-user chat in chatrooms</li> <li>Multi-user chat in chatrooms (<a href="http://xmpp.org/extensions/xep-0045.html">XEP 45</a>)</li>
<li>Chatroom Topics</li> <li>Chatroom Topics</li>
<li>vCard support</li> <li>vCard support (<a href="http://xmpp.org/extensions/xep-0054.html">XEP 54</a>)</li>
</ul> </ul>
<h2>CMS Integration</h2>
<p><strong>Converse.js</strong> is available as an add-on for the <a href="http://plone.org" target="_blank">Plone</a> CMS, called <a href="http://github.com/collective/collective.xmpp.chat" target="_blank">collective.xmpp.chat</a>.</p>
<p>If you have integrated Converse.js into any other CMS or framework,
<a href="http://opkode.com/contact" target="_blank">please let me know</a> and I'll mention it on this page.</p>
<h2>Screencasts</h2> <h2>Screencasts</h2>
<ul> <ul>
<li><a href="http://opkode.com/media/blog/instant-messaging-for-plone-with-javascript-and-xmpp" target="_blank">Screencast 1</a>: <li><a href="http://opkode.com/media/blog/instant-messaging-for-plone-with-javascript-and-xmpp" target="_blank">Screencast 1</a>:
@ -58,39 +75,27 @@
</ul> </ul>
<h2>Demo</h2> <h2>Demo</h2>
<p>
The code in Converse.js is pretty solid and already used in production
in Plone installations. It's however not yet 100% ready for prime-time
as a standalone client.
</p>
<p>
Nevertheless, you can try out the current functionality on this page.
</p>
<p> <p>
<a href="#" class="chat toggle-online-users">Click this link</a> or <a href="#" class="chat toggle-online-users">Click this link</a> or
click the link on the bottom right corner. click the link on the bottom right corner of this page.
</a> </a>
</p> </p>
<p> <p>
Besides providing valid credentials for an XMPP/Jabber account, you'll also have to provide You can log in with any existing federated Jabber/XMPP account, or create a new one at any of these providers:
the details of a <a target="_blank" href="http://metajack.im/2008/09/08/which-bosh-server-do-you-need">BOSH Connection Manager</a>. <ul>
I intend to set up a connection manager for people to play with in the <li><a href="http://jabber.org" target="_blank">jabber.org</a></li>
near future, but for the moment I unfortunately can't help you there. <li><a href="https://jappix.com" target="_blank">jappix.com</a></li>
<li><a href="https://gmail.com" target="_blank">gmail.com</a></li>
</ul>
</p> </p>
<p> <p>
You can create a Jabber/XMPP account at any of these providers: The chat client will disconnect whenever you reload the page. If you
<ul> want the user's session to persist across page reloads, you can
<li> establish an authenticated connection on the server side and then attach to
<a href="http://jabber.org" target="_blank">jabber.org</a> this connection in your browser.
</li> </p>
</li> <p><strong>Converse.js</strong> already supports this usecase, but you'll have to
<li> do more manual work yourself.
<a href="https://jappix.com" target="_blank">jappix.com</a>
</li>
<li>
<a href="https://gmail.com" target="_blank">gmail.com</a>
</li>
</ul>
</p> </p>
<h2>Tests</h2> <h2>Tests</h2>

View File

@ -1,5 +1,6 @@
require(["jquery", "converse"], function($, converse) { require(["jquery", "converse"], function($, converse) {
converse.initialize({ converse.initialize({
bosh_service_url: 'https://bind.opkode.im',
prebind: false, prebind: false,
xhr_user_search: false, xhr_user_search: false,
auto_subscribe: false auto_subscribe: false