瀏覽代碼

Remove ChatBox views when they get closed.

Previously views were only hidden, but not removed. This was an unnecessary
"optimization" which introduced unnecessary complexity.

Problem solved was that closing minimized chats didn't dereference the model
for hidden "normal" chat views, causing an exception to be raised when trying
to log out.
JC Brand 9 年之前
父節點
當前提交
ed4b9a85cc
共有 4 個文件被更改,包括 34 次插入9 次删除
  1. 6 3
      src/converse-chatview.js
  2. 10 0
      src/converse-core.js
  3. 9 2
      src/converse-minimize.js
  4. 9 4
      src/converse-muc.js

+ 6 - 3
src/converse-chatview.js

@@ -765,11 +765,14 @@
                 close: function (ev) {
                     if (ev && ev.preventDefault) { ev.preventDefault(); }
                     if (converse.connection.connected) {
+                        // Immediately sending the chat state, because the
+                        // model is going to be destroyed afterwards.
+                        this.model.set('chat_state', converse.INACTIVE);
+                        this.sendChatState();
+
                         this.model.destroy();
-                        this.setChatState(converse.INACTIVE);
-                    } else {
-                        this.hide();
                     }
+                    this.remove();
                     converse.emit('chatBoxClosed', this);
                     return this;
                 },

+ 10 - 0
src/converse-core.js

@@ -1411,6 +1411,7 @@
 
             initialize: function () {
                 this.model.on("add", this.onChatBoxAdded, this);
+                this.model.on("destroy", this.removeChat, this);
             },
 
             _ensureElement: function () {
@@ -1432,7 +1433,12 @@
 
             onChatBoxAdded: function (item) {
                 var view = this.get(item.get('id'));
+                // Views aren't created here, since the core code doesn't have
+                // contain any views. Instead, they're created in overrides in
+                // converse-chatiew.js and/or converse-muc.js
                 if (view) {
+                    // This is an optimization. We don't remove older views, so
+                    // when one is available, we reuse it.
                     delete view.model; // Remove ref to old model to help garbage collection
                     view.model = item;
                     view.initialize();
@@ -1440,6 +1446,10 @@
                 return view;
             },
 
+            removeChat: function (item) {
+                this.remove(item.get('id'));
+            },
+
             closeAllChatBoxes: function () {
                 /* This method gets overridden in src/converse-controlbox.js if
                  * the controlbox plugin is active.

+ 9 - 2
src/converse-minimize.js

@@ -223,8 +223,15 @@
                 close: function (ev) {
                     if (ev && ev.preventDefault) { ev.preventDefault(); }
                     this.remove();
-                    this.model.destroy();
-                    converse.emit('chatBoxClosed', this);
+                    var view = converse.chatboxviews.get(this.model.get('id'));
+                    if (view) {
+                        // This will call model.destroy(), removing it from the
+                        // collection and will also emit 'chatBoxClosed'
+                        view.close();
+                    } else {
+                        this.model.destroy();
+                        converse.emit('chatBoxClosed', this);
+                    }
                     return this;
                 },
 

+ 9 - 4
src/converse-muc.js

@@ -192,9 +192,6 @@
                             this.maximize();
                         }
                     }, this);
-                    this.model.on('destroy', function () {
-                        this.hide().leave();
-                    }, this);
 
                     this.occupantsview = new converse.ChatRoomOccupantsView({
                         model: new converse.ChatRoomOccupants({nick: this.model.get('nick')})
@@ -243,6 +240,12 @@
                     return this;
                 },
 
+                close: function (ev) {
+                    converse.connection.deleteHandler(this.handler);
+                    this.leave();
+                    converse.ChatBoxView.prototype.close.apply(this, arguments);
+                },
+
                 toggleOccupants: function (ev, preserve_state) {
                     if (ev) {
                         ev.preventDefault();
@@ -545,7 +548,9 @@
                         presence.c("status", exit_msg);
                     }
                     converse.connection.addHandler(
-                        function () { this.model.set('connection_status', Strophe.Status.DISCONNECTED); }.bind(this),
+                        function () {
+                            this.model.set('connection_status', Strophe.Status.DISCONNECTED);
+                        }.bind(this),
                         null, "presence", null, presenceid);
                     converse.connection.send(presence);
                 },