瀏覽代碼

MUC: only render and listen to 'scroll' event...

after the cached messages have been fetched.
JC Brand 8 年之前
父節點
當前提交
f8d9368163
共有 4 個文件被更改,包括 52 次插入30 次删除
  1. 22 7
      spec/chatroom.js
  2. 6 3
      spec/controlbox.js
  3. 13 8
      src/converse-muc.js
  4. 11 12
      tests/utils.js

+ 22 - 7
spec/chatroom.js

@@ -14,26 +14,32 @@
             it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments", mock.initConverse(function (_converse) {
                 test_utils.createContacts(_converse, 'current');
                 runs(function () {
-                    test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
-                    test_utils.openChatRoom(_converse, 'leisure', 'localhost', 'dummy');
-                    test_utils.openChatRoom(_converse, 'news', 'localhost', 'dummy');
+                    test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
+                    test_utils.openAndEnterChatRoom(_converse, 'leisure', 'localhost', 'dummy');
+                    test_utils.openAndEnterChatRoom(_converse, 'news', 'localhost', 'dummy');
                     expect(_converse.chatboxviews.get('lounge@localhost').$el.is(':visible')).toBeTruthy();
                     expect(_converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy();
                     expect(_converse.chatboxviews.get('news@localhost').$el.is(':visible')).toBeTruthy();
                 });
                 waits('100');
                 runs(function () {
+                    // XXX: bit of a cheat here. We want `cleanup()` to be
+                    // called on the room. Either it's this or faking
+                    // `sendPresence`.
+                    _converse.connection.connected = false;
+
                     _converse.api.rooms.close('lounge@localhost');
                     expect(_converse.chatboxviews.get('lounge@localhost')).toBeUndefined();
                     expect(_converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy();
                     expect(_converse.chatboxviews.get('news@localhost').$el.is(':visible')).toBeTruthy();
+
                     _converse.api.rooms.close(['leisure@localhost', 'news@localhost']);
                     expect(_converse.chatboxviews.get('lounge@localhost')).toBeUndefined();
                     expect(_converse.chatboxviews.get('leisure@localhost')).toBeUndefined();
                     expect(_converse.chatboxviews.get('news@localhost')).toBeUndefined();
 
-                    test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
-                    test_utils.openChatRoom(_converse, 'leisure', 'localhost', 'dummy');
+                    test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
+                    test_utils.openAndEnterChatRoom(_converse, 'leisure', 'localhost', 'dummy');
                     expect(_converse.chatboxviews.get('lounge@localhost').$el.is(':visible')).toBeTruthy();
                     expect(_converse.chatboxviews.get('leisure@localhost').$el.is(':visible')).toBeTruthy();
                 });
@@ -49,7 +55,7 @@
                 test_utils.createContacts(_converse, 'current');
                 waits('300'); // ChatBox.show() is debounced for 250ms
                 runs(function () {
-                    test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
+                    test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
                     var jid = 'lounge@localhost';
                     var room = _converse.api.rooms.get(jid);
                     expect(room instanceof Object).toBeTruthy();
@@ -61,7 +67,7 @@
                 waits('300'); // ChatBox.show() is debounced for 250ms
                 runs(function () {
                     // Test with mixed case
-                    test_utils.openChatRoom(_converse, 'Leisure', 'localhost', 'dummy');
+                    test_utils.openAndEnterChatRoom(_converse, 'Leisure', 'localhost', 'dummy');
                     var jid = 'Leisure@localhost';
                     var room = _converse.api.rooms.get(jid);
                     expect(room instanceof Object).toBeTruthy();
@@ -91,6 +97,15 @@
             }));
 
            it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box", mock.initConverse(function (_converse) {
+                // Mock 'getRoomFeatures', otherwise the room won't be
+                // displayed as it waits first for the features to be returned
+                // (when it's a new room being created).
+                spyOn(_converse.ChatRoomView.prototype, 'getRoomFeatures').andCallFake(function () {
+                    var deferred = new $.Deferred();
+                    deferred.resolve();
+                    return deferred.promise();
+                });
+
                 test_utils.createContacts(_converse, 'current');
                 var chatroomview;
                 var jid = 'lounge@localhost';

+ 6 - 3
spec/controlbox.js

@@ -1140,14 +1140,17 @@
                 expect($server.length).toBe(1);
                 expect($('.chatroom:visible').length).toBe(0); // There shouldn't be any chatrooms open currently
                 spyOn(roomspanel, 'createChatRoom').andCallThrough();
+                spyOn(_converse.ChatRoomView.prototype, 'getRoomFeatures').andCallFake(function () {
+                    var deferred = new $.Deferred();
+                    deferred.resolve();
+                    return deferred.promise();
+                });
+
                 roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
                 runs(function () {
                     $input.val('Lounge');
                     $nick.val('dummy');
                     $server.val('muc.localhost');
-                });
-                waits('250');
-                runs(function () {
                     roomspanel.$el.find('form').submit();
                     expect(roomspanel.createChatRoom).toHaveBeenCalled();
                 });

+ 13 - 8
src/converse-muc.js

@@ -352,15 +352,9 @@
                     this.model.on('change:name', this.renderHeading, this);
 
                     this.createOccupantsView();
-                    this.render().insertIntoDOM(); // TODO: hide chat area until messages received.
-                    // XXX: adding the event below to the declarative events map doesn't work.
-                    // The code that gets executed because of that looks like this:
-                    //      this.$el.on('scroll', '.chat-content', this.markScrolled.bind(this));
-                    // Which for some reason doesn't work.
-                    // So working around that fact here:
-                    this.$el.find('.chat-content').on('scroll', this.markScrolled.bind(this));
-
+                    this.render();
                     this.registerHandlers();
+
                     if (this.model.get('connection_status') !==  ROOMSTATUS.ENTERED) {
                         this.getRoomFeatures().always(function () {
                             that.join();
@@ -416,9 +410,13 @@
                     this.occupantsview.model.browserStorage = new Backbone.BrowserStorage.session(id);
                     this.occupantsview.render();
                     this.occupantsview.model.fetch({add:true});
+                    return this;
                 },
 
                 insertIntoDOM: function () {
+                    if (document.querySelector('body').contains(this.el)) {
+                        return;
+                    }
                     var view = _converse.chatboxviews.get("controlbox");
                     if (view) {
                         this.$el.insertAfter(view.$el);
@@ -460,6 +458,13 @@
                     }
                 },
 
+                afterMessagesFetched: function () {
+                    _converse.ChatBoxView.prototype.afterMessagesFetched.apply(this, arguments);
+                    // We only start listening for the scroll event after
+                    // cached messages have been fetched
+                    this.$('.chat-content').on('scroll', this.markScrolled.bind(this));
+                },
+
                 getExtraMessageClasses: function (attrs) {
                     var extra_classes = _converse.ChatBoxView.prototype
                             .getExtraMessageClasses.apply(this, arguments);

+ 11 - 12
tests/utils.js

@@ -101,28 +101,25 @@
         return converse.roster.get(jid).trigger("open");
     };
 
-    utils.openChatRoom = function (converse, room, server, nick) {
-        // Open a new chatroom
-        this.openControlBox(converse);
-        this.openRoomsPanel(converse);
-        var roomspanel = converse.chatboxviews.get('controlbox').roomspanel;
+    utils.openChatRoom = function (_converse, room, server, nick) {
+        // Opens a new chatroom
+        this.openControlBox(_converse);
+        this.openRoomsPanel(_converse);
+        var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
         roomspanel.$el.find('input.new-chatroom-name').val(room);
         roomspanel.$el.find('input.new-chatroom-nick').val(nick);
         roomspanel.$el.find('input.new-chatroom-server').val(server);
         roomspanel.$el.find('form').submit();
-        this.closeControlBox(converse);
+        this.closeControlBox(_converse);
     };
 
     utils.openAndEnterChatRoom = function (converse, room, server, nick) {
-        var IQ_id, sendIQ = converse.connection.sendIQ;
-        spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
-            IQ_id = sendIQ.bind(this)(iq, callback, errback);
-        });
-
+        sinon.spy(converse.connection, 'sendIQ');
         utils.openChatRoom(converse, room, server);
-        var view = converse.chatboxviews.get(room+'@'+server);
+        var view = converse.chatboxviews.get((room+'@'+server).toLowerCase());
 
         // We pretend this is a new room, so no disco info is returned.
+        var IQ_id = converse.connection.sendIQ.firstCall.returnValue;
         var features_stanza = $iq({
                 from: 'lounge@localhost',
                 'id': IQ_id,
@@ -133,6 +130,7 @@
         converse.connection._dataRecv(utils.createRequest(features_stanza));
 
         // The XMPP server returns the reserved nick for this user.
+        IQ_id = converse.connection.sendIQ.secondCall.returnValue;
         var stanza = $iq({
             'type': 'result',
             'id': IQ_id,
@@ -156,6 +154,7 @@
             }).up()
             .c('status').attrs({code:'110'});
         converse.connection._dataRecv(utils.createRequest(presence));
+        converse.connection.sendIQ.restore();
     };
 
     utils.removeRosterContacts = function () {