Browse Source

Show a list of current bookmarks in the "Rooms" panel

JC Brand 8 years ago
parent
commit
0020be34d7

+ 6 - 4
config.js

@@ -124,15 +124,18 @@ require.config({
         "action":                   "src/templates/action",
         "add_contact_dropdown":     "src/templates/add_contact_dropdown",
         "add_contact_form":         "src/templates/add_contact_form",
+        "bookmark":                 "src/templates/bookmark",
+        "bookmarks_list":           "src/templates/bookmarks_list",
         "change_status_message":    "src/templates/change_status_message",
         "chat_status":              "src/templates/chat_status",
         "chatarea":                 "src/templates/chatarea",
         "chatbox":                  "src/templates/chatbox",
+        "chatbox_minimize":         "src/templates/chatbox_minimize",
         "chatroom":                 "src/templates/chatroom",
-        "chatroom_form":            "src/templates/chatroom_form",
         "chatroom_bookmark_form":   "src/templates/chatroom_bookmark_form",
-        "chatroom_password_form":   "src/templates/chatroom_password_form",
+        "chatroom_form":            "src/templates/chatroom_form",
         "chatroom_nickname_form":   "src/templates/chatroom_nickname_form",
+        "chatroom_password_form":   "src/templates/chatroom_password_form",
         "chatroom_sidebar":         "src/templates/chatroom_sidebar",
         "chatrooms_tab":            "src/templates/chatrooms_tab",
         "chats_panel":              "src/templates/chats_panel",
@@ -172,8 +175,7 @@ require.config({
         "toggle_chats":             "src/templates/toggle_chats",
         "toolbar":                  "src/templates/toolbar",
         "toolbar_otr":              "src/templates/toolbar_otr",
-        "trimmed_chat":             "src/templates/trimmed_chat",
-        "chatbox_minimize":         "src/templates/chatbox_minimize"
+        "trimmed_chat":             "src/templates/trimmed_chat"
     },
 
     map: {

+ 17 - 1
css/converse.css

@@ -1615,7 +1615,8 @@
   #conversejs #controlbox #chatrooms form.add-chatroom input[type=text] {
     width: 100%; }
   #conversejs #controlbox #chatrooms #available-chatrooms {
-    padding: 0 1em 2em 1em;
+    margin: 0 1em;
+    padding: 0;
     text-align: left; }
     #conversejs #controlbox #chatrooms #available-chatrooms dt {
       border: none;
@@ -2166,4 +2167,19 @@
     right: 116px;
     bottom: 10px; }
 
+#conversejs #controlbox .bookmarks-list {
+  margin-top: 1em; }
+  #conversejs #controlbox .bookmarks-list .bookmarks-toggle {
+    display: block;
+    font-weight: bold;
+    color: #818479; }
+  #conversejs #controlbox .bookmarks-list .bookmarks li {
+    padding: 1em 1em; }
+    #conversejs #controlbox .bookmarks-list .bookmarks li .open-room {
+      float: left; }
+    #conversejs #controlbox .bookmarks-list .bookmarks li .room-info {
+      float: right; }
+    #conversejs #controlbox .bookmarks-list .bookmarks li .remove-bookmark {
+      float: right; }
+
 /*# sourceMappingURL=converse.css.map */

+ 26 - 0
sass/_bookmarks.scss

@@ -0,0 +1,26 @@
+#conversejs {
+    #controlbox {
+        .bookmarks-list {
+            margin-top: 1em;
+            .bookmarks-toggle {
+                display: block;
+                font-weight: bold;
+                color: $text-color;
+            }
+            .bookmarks {
+                li {
+                    padding: 1em 1em;
+                    .open-room {
+                        float: left;
+                    }
+                    .room-info {
+                        float: right;
+                    }
+                    .remove-bookmark {
+                        float: right;
+                    }
+                }
+            }
+        }
+    }
+}

+ 2 - 1
sass/_controlbox.scss

@@ -116,7 +116,8 @@
                 }
             }
             #available-chatrooms {
-                padding: 0 1em 2em 1em;
+                margin: 0 1em;
+                padding: 0;
                 text-align: left;
                 dt {
                     border: none;

+ 1 - 0
sass/converse.scss

@@ -17,3 +17,4 @@
 @import "chatrooms";
 @import "headline";
 @import "minimized_chats";
+@import "bookmarks";

+ 35 - 4
spec/bookmarks.js

@@ -123,7 +123,7 @@
             // nothing to test for here.
         });
 
-        it("will be automatilly opened if 'autojoin' is set on the bookmark", function () {
+        it("will be automatically opened if 'autojoin' is set on the bookmark", function () {
             var jid = 'lounge@localhost';
             converse.bookmarks.create({
                 'jid': jid,
@@ -198,11 +198,9 @@
                     var $bookmark_icon = view.$('.icon-pushpin');
                     expect($bookmark_icon.hasClass('button-on')).toBeTruthy();
                     $bookmark_icon.click();
-                    expect(converse.bookmarks.sendBookmarkStanza).toHaveBeenCalled();
-                    expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
                     expect(view.toggleBookmark).toHaveBeenCalled();
+                    expect($bookmark_icon.hasClass('button-on')).toBeFalsy();
                     expect(converse.bookmarks.length).toBe(0);
-
                     // Check that an IQ stanza is sent out, containing no
                     // conferences to bookmark (since we removed the one and
                     // only bookmark).
@@ -383,5 +381,38 @@
             expect(converse.bookmarks.findWhere({'jid': 'theplay@conference.shakespeare.lit'}).get('autojoin')).toBe(true);
             expect(converse.bookmarks.findWhere({'jid': 'another@conference.shakespeare.lit'}).get('autojoin')).toBe(false);
         });
+
+        describe("The rooms panel", function () {
+            beforeEach(function () {
+                test_utils.openRoomsPanel();
+            });
+
+            it("shows a list of bookmarks", function () {
+                var IQ_id;
+                var sendIQ = converse.connection.sendIQ;
+                spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
+                    IQ_id = sendIQ.bind(this)(iq, callback, errback);
+                });
+                converse.emit('connected');
+                var stanza = $iq({'to': converse.connection.jid, 'type':'result', 'id':IQ_id})
+                    .c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
+                        .c('items', {'node': 'storage:bookmarks'})
+                            .c('item', {'id': 'current'})
+                                .c('storage', {'xmlns': 'storage:bookmarks'})
+                                    .c('conference', {
+                                        'name': 'The Play's the Thing',
+                                        'autojoin': 'false',
+                                        'jid': 'theplay@conference.shakespeare.lit'
+                                    }).c('nick').t('JC').up().up()
+                                    .c('conference', {
+                                        'name': 'Another room',
+                                        'autojoin': 'false',
+                                        'jid': 'another@conference.shakespeare.lit'
+                                    }).c('nick').t('JC').up().up();
+                converse.connection._dataRecv(test_utils.createRequest(stanza));
+                expect(converse.bookmarks.models.length).toBe(2);
+                expect($('#chatrooms ul.bookmarks li').length).toBe(2);
+            });
+        });
     });
 }));

+ 88 - 11
src/converse-bookmarks.js

@@ -19,18 +19,29 @@
             "converse-core",
             "converse-api",
             "converse-muc",
-            "tpl!chatroom_bookmark_form"
+            "tpl!chatroom_bookmark_form",
+            "tpl!bookmark",
+            "tpl!bookmarks_list"
         ],
         factory);
-}(this, function ($, _, moment, strophe, utils, converse, converse_api, muc, chatroom_bookmark_form) {
+}(this, function (
+        $, _, moment, strophe, utils,
+        converse, converse_api, muc,
+        tpl_chatroom_bookmark_form,
+        tpl_bookmark,
+        tpl_bookmarks_list
+    ) {
 
     var __ = utils.__.bind(converse),
+        ___ = utils.___,
         Strophe = converse_api.env.Strophe,
         $iq = converse_api.env.$iq,
         b64_sha1 = converse_api.env.b64_sha1;
 
     // Add new HTML templates.
-    converse.templates.chatroom_bookmark_form = chatroom_bookmark_form;
+    converse.templates.chatroom_bookmark_form = tpl_chatroom_bookmark_form;
+    converse.templates.bookmark = tpl_bookmark;
+    converse.templates.bookmarks_list = tpl_bookmarks_list;
 
     converse_api.plugins.add('converse-bookmarks', {
         overrides: {
@@ -40,10 +51,6 @@
             //
             // New functions which don't exist yet can also be added.
 
-            RoomsPanel: {
-                /* TODO: show bookmarked rooms in the rooms panel */
-            },
-
             ChatRoomView: {
                 events: {
                     'click .toggle-bookmark': 'toggleBookmark'
@@ -125,7 +132,6 @@
                         'nick':  $form.find('input[name=nick]').val()
                     });
                     this.model.save('bookmarked', true);
-                    converse.bookmarks.sendBookmarkStanza();
                     this.$el.find('div.chatroom-form-container').hide(
                         function () {
                             $(this).remove();
@@ -143,9 +149,6 @@
                         this.renderBookmarkForm();
                     } else {
                         converse.bookmarks.remove(models);
-                        converse.bookmarks.sendBookmarkStanza().fail(
-                            _.partial(this.model.save, 'bookmarked', false)
-                        );
                         this.$('.icon-pushpin').removeClass('button-on');
                     }
                 }
@@ -166,7 +169,9 @@
                 initialize: function () {
                     this.on('add', this.markRoomAsBookmarked, this);
                     this.on('add', this.openBookmarkedRoom, this);
+                    this.on('add', this.sendBookmarkStanza, this);
                     this.on('remove', this.markRoomAsUnbookmarked, this);
+                    this.on('remove', this.sendBookmarkStanza, this);
 
                     this.browserStorage = new Backbone.BrowserStorage[converse.storage](
                         b64_sha1('converse.room-bookmarks'+converse.bare_jid)
@@ -288,9 +293,81 @@
                 }
             });
 
+            converse.BookmarksView = Backbone.View.extend({
+                tagName: 'div',
+                className: 'bookmarks-list',
+                events: {
+                    'click .remove-bookmark': 'removebookmark',
+                    'click .bookmarks-toggle': 'toggleBookmarksList'
+                },
+
+                initialize: function () {
+                    this.model.on('add', this.onBookmarkAdded, this);
+                },
+
+                render: function (cfg) {
+                    this.$el.html(converse.templates.bookmarks_list({
+                        'toggle_state': converse.OPENED,
+                        'desc_bookmarks': __('Click to toggle the bookmarks list'),
+                        'label_bookmarks': __('Bookmarked Rooms')
+                    }));
+                    this.$bookmarks = this.$('.bookmarks');
+                    var controlboxview = converse.chatboxviews.get('controlbox');
+                    if (_.isUndefined(controlboxview)) {
+                        return this.$el;
+                    }
+                    controlboxview.$('#chatrooms .bookmarks-list').remove();
+                    this.$el.prependTo(controlboxview.$('#chatrooms'));
+                    return this.$el;
+                },
+
+                removeBookmark: function (ev) {
+                    ev.preventDefault();
+                    var name = $(ev.target).data('bookmarkName');
+                    var jid = $(ev.target).data('roomJid');
+                    if (confirm(__(___("Are you sure you want to remove the bookmark \"%1$s\"?"), name))) {
+                        var models = converse.bookmarks.where({'jid': jid});
+                        converse.bookmarks.remove(models);
+                    }
+                },
+
+                onBookmarkAdded: function (item) {
+                    if (_.isUndefined(this.$bookmarks)) {
+                        this.render();
+                    }
+                    this.$bookmarks.append($(
+                        converse.templates.bookmark({
+                            'name': item.get('name'),
+                            'jid': item.get('jid'),
+                            'open_title': __('Click to open this room'),
+                            'info_title': __('Show more information on this room'),
+                            'info_remove': __('Remove this bookmark')
+                        })
+                    ));
+                },
+
+                toggleBookmarksList: function (ev) {
+                    if (ev && ev.preventDefault) { ev.preventDefault(); }
+                    var $el = $(ev.target);
+                    if ($el.hasClass("icon-opened")) {
+                        this.$('.bookmarks').slideUp();
+                        $el.removeClass("icon-opened").addClass("icon-closed");
+                    } else {
+                        $el.removeClass("icon-closed").addClass("icon-opened");
+                        this.$('.bookmarks').slideDown();
+                    }
+                }
+            });
+
             converse.initBookmarks = function () {
                 converse.bookmarks = new converse.Bookmarks();
+                converse.bookmarksview = new converse.BookmarksView(
+                    {'model': converse.bookmarks}
+                );
                 converse.bookmarks.fetchBookmarks();
+                // TODO: think of performance here... we probably only want to
+                // show the bookmarks after they have been fetched
+                converse.bookmarksview.render();
             };
             converse.on('connected', converse.initBookmarks);
             converse.on('reconnected', converse.initBookmarks);

+ 7 - 7
src/converse-muc.js

@@ -1484,20 +1484,20 @@
 
                 showRoomInfo: function (ev) {
                     var target = ev.target,
-                        $dd = $(target).parent('dd'),
-                        $div = $dd.find('div.room-info');
+                        $parent = $(target).parent('dd'),
+                        $div = $parent.find('div.room-info');
                     if ($div.length) {
                         $div.remove();
                     } else {
-                        $dd.find('span.spinner').remove();
-                        $dd.append('<span class="spinner hor_centered"/>');
+                        $parent.find('span.spinner').remove();
+                        $parent.append('<span class="spinner hor_centered"/>');
                         converse.connection.disco.info(
                             $(target).attr('data-room-jid'),
                             null,
                             function (stanza) {
                                 var $stanza = $(stanza);
                                 // All MUC features found here: http://xmpp.org/registrar/disco-features.html
-                                $dd.find('span.spinner').replaceWith(
+                                $parent.find('span.spinner').replaceWith(
                                     converse.templates.room_description({
                                         'desc': $stanza.find('field[var="muc#roominfo_description"] value').text(),
                                         'occ': $stanza.find('field[var="muc#roominfo_occupants"] value').text(),
@@ -1533,7 +1533,7 @@
 
                 createChatRoom: function (ev) {
                     ev.preventDefault();
-                    var name, $name, server, $server, jid, chatroom;
+                    var name, $name, server, $server, jid;
                     if (ev.type === 'click') {
                         name = $(ev.target).text();
                         jid = $(ev.target).attr('data-room-jid');
@@ -1554,7 +1554,7 @@
                             return;
                         }
                     }
-                    chatroom = converse.chatboxviews.showChat({
+                    converse.chatboxviews.showChat({
                         'id': jid,
                         'jid': jid,
                         'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)),

+ 7 - 0
src/templates/bookmark.html

@@ -0,0 +1,7 @@
+<li>
+    <a class="open-room" data-room-jid="{{jid}}" title="{{open_title}}" href="#">{{name}}</a>
+    <a class="remove-bookmark icon-close" data-room-jid="{{jid}}" data-bookmark-name="{{name}}"
+       title="{{info_remove}}" href="#">&nbsp;</a>
+    <a class="room-info icon-room-info" data-room-jid="{{jid}}"
+       title="{{info_title}}" href="#">&nbsp;</a>
+</li>

+ 2 - 0
src/templates/bookmarks_list.html

@@ -0,0 +1,2 @@
+<a href="#" class="bookmarks-toggle icon-{{toggle_state}}" title="{{desc_bookmarks}}">{{label_bookmarks}}</a>
+<ul class="bookmarks"></ul>