diff --git a/css/converse.css b/css/converse.css
index 732e57764..451c2477d 100644
--- a/css/converse.css
+++ b/css/converse.css
@@ -1989,6 +1989,9 @@
#conversejs .chatroom .room-invite .tt-dropdown-menu .tt-suggestion .tt-highlight {
background-color: #D24E2B; }
+#conversejs .chatbox.headlines .chat-head.chat-head-chatbox {
+ background-color: #2A9D8F; }
+
#conversejs #minimized-chats {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
diff --git a/docs/CHANGES.md b/docs/CHANGES.md
index 46f80444f..4567dc208 100755
--- a/docs/CHANGES.md
+++ b/docs/CHANGES.md
@@ -2,8 +2,11 @@
## 0.11.0 (Unreleased)
+- Add support for messages with type `headline`, often used for notifications
+ from the server. [jcbrand]
- Add stanza-specific event listener `converse.listen.stanza`.
- As a result `converse.listen.on('message');` has been deprecated, use `converse.stanza.on('message');` instead. [jcbrand]
+ As a result `converse.listen.on('message');` has been deprecated, use
+ `converse.stanza.on('message');` instead. [jcbrand]
- Emit an event `chatBoxInitialized` once a chat box's initialize method has been called. [jcbrand]
- Emit an event `statusInitialized` once the user's own status has been initialized upon startup. [jcbrand]
- New config option [chatstate_notification_blacklist](https://conversejs.org/docs/html/configuration.html#chatstate_notification_blacklist) [jcbrand]
@@ -12,8 +15,9 @@
encrypted session. [jcbrand]
- Bugfix: RID, SID and JID tokens ignored when `keepalive` set to `true`. [jcbrand]
- Removed the `account.logout` API, instead use `user.logout`. [jcbrand]
-- Use `rel=noopener` with links that contain `target=_blank` to prevent potential phishing attacks.
- [More info here](https://mathiasbynens.github.io/rel-noopener/) [jcbrand]
+- Use `rel=noopener` with links that contain `target=_blank` to prevent potential
+ phishing attacks. [More info here](https://mathiasbynens.github.io/rel-noopener/)
+ [jcbrand]
- #261 `show_controlbox_by_default` config not working [diditopher]
- #443 HTML5 notifications of received messages [jcbrand]
- #534 Updated Russian translation [badfiles]
@@ -22,7 +26,8 @@
- #577 New config variable [message_archiving_timeout](https://conversejs.org/docs/html/configuration.html#message_archiving_timeout) [jcbrand]
- #587 Fix issue when logging out with `auto_logout=true` [davec82]
- #589 Save scroll position on minimize and restore it on maximize [rlanvin]
-- #592 Add random resource for `auto_login`, add method generateResource to generate random resource [davec82]
+- #592 Add random resource for `auto_login`, add method generateResource to
+ generate random resource [davec82]
- #598 Add option `synchronize_availability` [davec82]
- #600 Fix change xmpp status also on icon-status click [davec82]
diff --git a/sass/_headline.scss b/sass/_headline.scss
new file mode 100644
index 000000000..2ab179278
--- /dev/null
+++ b/sass/_headline.scss
@@ -0,0 +1,10 @@
+#conversejs {
+ .chatbox.headlines {
+ .chat-head {
+ &.chat-head-chatbox {
+ background-color: $headline-head-color;
+ }
+ }
+ }
+}
+
diff --git a/sass/_variables.scss b/sass/_variables.scss
index 581c96ac0..8fdc19de5 100644
--- a/sass/_variables.scss
+++ b/sass/_variables.scss
@@ -63,6 +63,8 @@ $chatroom-head-color: #E76F51 !default;
$chatroom-color-light: #FF977C !default;
$chatroom-color-dark: #D24E2B !default;
+$headline-head-color: #2A9D8F !default;
+
$box-close-button-padding-top: 4px !default;
$box-close-button-padding-bottom: 4px !default;
$box-close-button-padding-left: 4px !default;
diff --git a/sass/converse.scss b/sass/converse.scss
index 6ca0be033..03f16eba7 100644
--- a/sass/converse.scss
+++ b/sass/converse.scss
@@ -15,4 +15,5 @@
@import "controlbox";
@import "roster";
@import "chatrooms";
+@import "headline";
@import "minimized_chats";
diff --git a/spec/headline.js b/spec/headline.js
new file mode 100644
index 000000000..a7703a301
--- /dev/null
+++ b/spec/headline.js
@@ -0,0 +1,56 @@
+/*global converse */
+(function (root, factory) {
+ define([
+ "jquery",
+ "mock",
+ "test_utils"
+ ], function ($, mock, test_utils) {
+ return factory($, mock, test_utils);
+ }
+ );
+} (this, function ($, mock, test_utils) {
+ "use strict";
+ var $msg = converse_api.env.$msg,
+ _ = converse_api.env._;
+
+ describe("When a headline message is received", function () {
+
+ it("a chat box will open and display it", function () {
+ /*
+ *
+ * SIEVE
+ * <juliet@example.com> You got mail.
+ *
+ *
+ * imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18
+ *
+ *
+ *
+ */
+ runs(function () {
+ var stanza = $msg({
+ 'type': 'headline',
+ 'from': 'notify.example.com',
+ 'to': 'dummy@localhost',
+ 'xml:lang': 'en'
+ })
+ .c('subject').t('SIEVE').up()
+ .c('body').t('<juliet@example.com> You got mail.').up()
+ .c('x', {'xmlns': 'jabber:x:oob'})
+ .c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
+ converse.connection._dataRecv(test_utils.createRequest(stanza));
+ });
+ waits(250);
+ runs(function () {
+ expect(
+ _.contains(
+ converse.chatboxviews.keys(),
+ 'notify.example.com')
+ ).toBeTruthy();
+ });
+ });
+ });
+}));
diff --git a/src/converse-core.js b/src/converse-core.js
index c56dbc764..ef4139276 100755
--- a/src/converse-core.js
+++ b/src/converse-core.js
@@ -1264,8 +1264,7 @@
});
}
});
-
-
+
this.ChatBoxes = Backbone.Collection.extend({
model: converse.ChatBox,
comparator: 'time_opened',
diff --git a/src/converse-headline.js b/src/converse-headline.js
index 1d0d9c7f5..920547256 100644
--- a/src/converse-headline.js
+++ b/src/converse-headline.js
@@ -4,25 +4,113 @@
// Copyright (c) 2012-2016, Jan-Carel Brand
// Licensed under the Mozilla Public License (MPLv2)
//
-/*global define */
+/*global define, window */
(function (root, factory) {
define("converse-headline", [
"converse-core",
"converse-api",
- // TODO: remove this dependency
"converse-chatview"
], factory);
}(this, function (converse, converse_api) {
"use strict";
+ var $ = converse_api.env.jQuery,
+ _ = converse_api.env._,
+ utils = converse_api.env.utils,
+ __ = utils.__.bind(converse);
+
+ var onHeadlineMessage = function (message) {
+ /* Handler method for all incoming messages of type "headline".
+ */
+ var $message = $(message),
+ bare_jid = $message.attr('from');
+ converse.chatboxes.create({
+ 'id': bare_jid,
+ 'jid': bare_jid,
+ 'fullname': bare_jid,
+ 'type': 'headline'
+ }).createMessage($message);
+ converse.emit('message', message);
+ return true;
+ };
converse_api.plugins.add('headline', {
+ overrides: {
+ // Overrides mentioned here will be picked up by converse.js's
+ // plugin architecture they will replace existing methods on the
+ // relevant objects or classes.
+ //
+ // New functions which don't exist yet can also be added.
+
+ ChatBoxViews: {
+ onChatBoxAdded: function (item) {
+ var view = this.get(item.get('id'));
+ if (!view && item.get('type') === 'headline') {
+ view = new converse.HeadlinesBoxView({model: item});
+ this.add(item.get('id'), view);
+ return view;
+ } else {
+ return this._super.onChatBoxAdded.apply(this, arguments);
+ }
+ }
+ }
+ },
+
initialize: function () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
- // TODO
+ converse.HeadlinesBoxView = converse.ChatBoxView.extend({
+ className: 'chatbox headlines',
+
+ events: {
+ 'click .close-chatbox-button': 'close',
+ 'click .toggle-chatbox-button': 'minimize',
+ 'keypress textarea.chat-textarea': 'keyPressed',
+ 'mousedown .dragresize-top': 'onStartVerticalResize',
+ 'mousedown .dragresize-left': 'onStartHorizontalResize',
+ 'mousedown .dragresize-topleft': 'onStartDiagonalResize'
+ },
+
+ initialize: function () {
+ $(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
+ this.model.messages.on('add', this.onMessageAdded, this);
+ this.model.on('show', this.show, this);
+ this.model.on('destroy', this.hide, this);
+ this.model.on('change:minimized', this.onMinimizedChanged, this);
+ this.render().fetchMessages().insertIntoPage().hide();
+ converse.emit('chatBoxInitialized', this);
+ },
+
+ render: function () {
+ this.$el.attr('id', this.model.get('box_id'))
+ .html(converse.templates.chatbox(
+ _.extend(this.model.toJSON(), {
+ show_toolbar: converse.show_toolbar,
+ show_textarea: false,
+ title: this.model.get('fullname'),
+ info_close: __('Close this box'),
+ info_minimize: __('Minimize this box'),
+ label_personal_message: ''
+ }
+ )
+ )
+ );
+ this.setWidth();
+ this.$content = this.$el.find('.chat-content');
+ converse.emit('chatBoxOpened', this);
+ window.setTimeout(utils.refreshWebkit, 50);
+ return this;
+ },
+ });
+
+ var registerHeadlineHandler = function () {
+ converse.connection.addHandler(
+ onHeadlineMessage, null, 'message', 'headline');
+ };
+ converse.on('connected', registerHeadlineHandler);
+ converse.on('reconnected', registerHeadlineHandler);
}
});
}));
diff --git a/src/converse-muc.js b/src/converse-muc.js
index 8cb9a4092..ef2ad5fac 100755
--- a/src/converse-muc.js
+++ b/src/converse-muc.js
@@ -4,7 +4,7 @@
// Copyright (c) 2012-2016, Jan-Carel Brand
// Licensed under the Mozilla Public License (MPLv2)
//
-/*global Backbone, define, window, setTimeout */
+/*global Backbone, define, window */
/* This is a Converse.js plugin which add support for multi-user chat rooms, as
* specified in XEP-0045 Multi-user chat.
@@ -14,8 +14,8 @@
"converse-core",
"converse-api",
"typeahead",
- // TODO remove next two dependencies
"converse-chatview",
+ // XXX: should we remove this dependency?
"converse-controlbox"
], factory);
}(this, function (converse, converse_api) {
@@ -221,6 +221,7 @@
length: 300,
tagName: 'div',
className: 'chatbox chatroom',
+ is_chatroom: true,
events: {
'click .close-chatbox-button': 'close',
'click .toggle-chatbox-button': 'minimize',
@@ -235,7 +236,6 @@
'mousedown .dragresize-left': 'onStartHorizontalResize',
'mousedown .dragresize-topleft': 'onStartDiagonalResize'
},
- is_chatroom: true,
initialize: function () {
$(window).on('resize', _.debounce(this.setDimensions.bind(this), 100));
@@ -278,7 +278,7 @@
this.renderChatArea();
this.$content.on('scroll', _.debounce(this.onScroll.bind(this), 100));
this.setWidth();
- setTimeout(converse.refreshWebkit, 50);
+ window.setTimeout(converse.refreshWebkit, 50);
return this;
},
diff --git a/tests/main.js b/tests/main.js
index 39aea35aa..8a5c42905 100644
--- a/tests/main.js
+++ b/tests/main.js
@@ -73,6 +73,7 @@ require([
"spec/notification",
"spec/profiling",
"spec/ping",
+ "spec/headline",
"spec/register",
"spec/xmppstatus"
], function () {