Ver Fonte

Support for showing headline messages.

JC Brand há 9 anos atrás
pai
commit
82aa9fec2c

+ 3 - 0
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;

+ 9 - 4
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]
 

+ 10 - 0
sass/_headline.scss

@@ -0,0 +1,10 @@
+#conversejs {
+    .chatbox.headlines {
+        .chat-head {
+            &.chat-head-chatbox {
+                background-color: $headline-head-color;
+            }
+        }
+    }
+}
+

+ 2 - 0
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;

+ 1 - 0
sass/converse.scss

@@ -15,4 +15,5 @@
 @import "controlbox";
 @import "roster";
 @import "chatrooms";
+@import "headline";
 @import "minimized_chats";

+ 56 - 0
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 () {
+            /*
+             *  <message from='notify.example.com'
+             *          to='romeo@im.example.com'
+             *          type='headline'
+             *          xml:lang='en'>
+             *  <subject>SIEVE</subject>
+             *  <body>&lt;juliet@example.com&gt; You got mail.</body>
+             *  <x xmlns='jabber:x:oob'>
+             *      <url>
+             *      imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18
+             *      </url>
+             *  </x>
+             *  </message>
+             */
+            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('&lt;juliet@example.com&gt; 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();
+            });
+        });
+    });
+}));

+ 1 - 2
src/converse-core.js

@@ -1264,8 +1264,7 @@
                 });
             }
         });
-
-
+        
         this.ChatBoxes = Backbone.Collection.extend({
             model: converse.ChatBox,
             comparator: 'time_opened',

+ 91 - 3
src/converse-headline.js

@@ -4,25 +4,113 @@
 // Copyright (c) 2012-2016, Jan-Carel Brand <jc@opkode.com>
 // 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);
         }
     });
 }));

+ 4 - 4
src/converse-muc.js

@@ -4,7 +4,7 @@
 // Copyright (c) 2012-2016, Jan-Carel Brand <jc@opkode.com>
 // 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;
                 },
 

+ 1 - 0
tests/main.js

@@ -73,6 +73,7 @@ require([
                 "spec/notification",
                 "spec/profiling",
                 "spec/ping",
+                "spec/headline",
                 "spec/register",
                 "spec/xmppstatus"
             ], function () {