Merge branch 'master' into gh-pages
This commit is contained in:
commit
093a7ecc4f
@ -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)
|
||||||
|
70
converse.js
70
converse.js
@ -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(
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
71
index.html
71
index.html
@ -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>
|
||||||
|
1
main.js
1
main.js
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user