Use an OrderedListView to render the bookmarks list

This commit is contained in:
JC Brand 2018-01-04 21:51:42 +00:00
parent 1d2bc11840
commit 5ea1b07b6b
3 changed files with 74 additions and 78 deletions

View File

@ -13,7 +13,8 @@
"use strict"; "use strict";
var $iq = converse.env.$iq, var $iq = converse.env.$iq,
Strophe = converse.env.Strophe, Strophe = converse.env.Strophe,
_ = converse.env._; _ = converse.env._,
u = converse.env.utils;
describe("A chat room", function () { describe("A chat room", function () {
@ -388,6 +389,7 @@
it("shows a list of bookmarks", mock.initConverseWithPromises( it("shows a list of bookmarks", mock.initConverseWithPromises(
['send'], ['rosterGroupsFetched'], {}, function (done, _converse) { ['send'], ['rosterGroupsFetched'], {}, function (done, _converse) {
test_utils.openControlBox().openRoomsPanel(_converse);
var IQ_id; var IQ_id;
expect(_.filter(_converse.connection.send.calls.all(), function (call) { expect(_.filter(_converse.connection.send.calls.all(), function (call) {
var stanza = call.args[0]; var stanza = call.args[0];
@ -419,6 +421,11 @@
'autojoin': 'false', 'autojoin': 'false',
'jid': 'theplay@conference.shakespeare.lit' 'jid': 'theplay@conference.shakespeare.lit'
}).c('nick').t('JC').up().up() }).c('nick').t('JC').up().up()
.c('conference', {
'name': '1st Bookmark',
'autojoin': 'false',
'jid': 'first@conference.shakespeare.lit'
}).c('nick').t('JC').up().up()
.c('conference', { .c('conference', {
'name': 'Bookmark with a very very long name that will be shortened', 'name': 'Bookmark with a very very long name that will be shortened',
'autojoin': 'false', 'autojoin': 'false',
@ -434,7 +441,15 @@
test_utils.waitUntil(function () { test_utils.waitUntil(function () {
return $('#chatrooms dl.bookmarks dd').length; return $('#chatrooms dl.bookmarks dd').length;
}, 300).then(function () { }, 300).then(function () {
expect($('#chatrooms dl.bookmarks dd').length).toBe(3); expect($('#chatrooms dl.bookmarks dd').length).toBe(4);
expect($('#chatrooms dl.bookmarks dd a').text().trim()).toBe(
"1st Bookmark  Another room  Bookmark with a very very long name that will be shortened  The Play's the Thing")
spyOn(window, 'confirm').and.returnValue(true);
$('#chatrooms dl.bookmarks dd:nth-child(2) a:nth-child(2)')[0].click();
expect(window.confirm).toHaveBeenCalled();
expect($('#chatrooms dl.bookmarks dd a').text().trim()).toBe(
"1st Bookmark  Bookmark with a very very long name that will be shortened  The Play's the Thing")
done(); done();
}); });
})); }));
@ -527,14 +542,11 @@
// Check that it disappears once the room is opened // Check that it disappears once the room is opened
var bookmark = _converse.bookmarksview.el.querySelector(".open-room"); var bookmark = _converse.bookmarksview.el.querySelector(".open-room");
bookmark.click(); bookmark.click();
room_els = _converse.bookmarksview.el.querySelectorAll(".open-room"); expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeTruthy();
expect(room_els.length).toBe(0);
// Check that it reappears once the room is closed // Check that it reappears once the room is closed
var view = _converse.chatboxviews.get(jid); var view = _converse.chatboxviews.get(jid);
view.close(); view.close();
room_els = _converse.bookmarksview.el.querySelectorAll(".open-room"); expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeFalsy();
expect(room_els.length).toBe(1);
done(); done();
})); }));
}); });

View File

@ -235,12 +235,6 @@
_converse.Bookmark = Backbone.Model; _converse.Bookmark = Backbone.Model;
_converse.BookmarksList = Backbone.Model.extend({
defaults: {
"toggle-state": _converse.OPENED
}
});
_converse.Bookmarks = Backbone.Collection.extend({ _converse.Bookmarks = Backbone.Collection.extend({
model: _converse.Bookmark, model: _converse.Bookmark,
comparator: 'name', comparator: 'name',
@ -385,18 +379,50 @@
} }
}); });
_converse.BookmarksView = Backbone.NativeView.extend({ _converse.BookmarksList = Backbone.Model.extend({
defaults: {
"toggle-state": _converse.OPENED
}
});
_converse.BookmarkView = Backbone.VDOMView.extend({
initialize () {
this.model.on('destroy', this.remove.bind(this));
},
toHTML () {
return tpl_bookmark({
'hidden': _converse.hide_open_bookmarks &&
_converse.chatboxes.where({'jid': this.model.get('jid')}).length,
'bookmarked': true,
'info_leave_room': __('Leave this room'),
'info_remove': __('Remove this bookmark'),
'info_remove_bookmark': __('Unbookmark this room'),
'info_title': __('Show more information on this room'),
'jid': this.model.get('jid'),
'name': this.model.get('name'),
'open_title': __('Click to open this room')
});
}
});
_converse.BookmarksView = Backbone.OrderedListView.extend({
tagName: 'div', tagName: 'div',
className: 'bookmarks-list rooms-list-container hidden', className: 'bookmarks-list rooms-list-container',
events: { events: {
'click .add-bookmark': 'addBookmark', 'click .add-bookmark': 'addBookmark',
'click .bookmarks-toggle': 'toggleBookmarksList', 'click .bookmarks-toggle': 'toggleBookmarksList',
'click .remove-bookmark': 'removeBookmark' 'click .remove-bookmark': 'removeBookmark'
}, },
listSelector: '.rooms-list',
ItemView: _converse.BookmarkView,
subviewIndex: 'jid',
initialize () { initialize () {
this.model.on('add', this.renderBookmarkListElement, this); Backbone.OrderedListView.prototype.initialize.apply(this, arguments);
this.model.on('remove', this.removeBookmarkListElement, this);
this.model.on('remove', this.hideListIfEmpty, this);
_converse.chatboxes.on('add', this.renderBookmarkListElement, this); _converse.chatboxes.on('add', this.renderBookmarkListElement, this);
_converse.chatboxes.on('remove', this.renderBookmarkListElement, this); _converse.chatboxes.on('remove', this.renderBookmarkListElement, this);
@ -408,6 +434,7 @@
); );
this.list_model.fetch(); this.list_model.fetch();
this.render(); this.render();
this.sortAndPositionAllItems();
}, },
render () { render () {
@ -417,7 +444,6 @@
'label_bookmarks': __('Bookmarks'), 'label_bookmarks': __('Bookmarks'),
'_converse': _converse '_converse': _converse
}); });
this.model.each(this.renderBookmarkListElement.bind(this));
const controlboxview = _converse.chatboxviews.get('controlbox'); const controlboxview = _converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview)) { if (!_.isUndefined(controlboxview)) {
const chatrooms_el = controlboxview.el.querySelector('#chatrooms'); const chatrooms_el = controlboxview.el.querySelector('#chatrooms');
@ -429,63 +455,21 @@
removeBookmark: _converse.removeBookmarkViaEvent, removeBookmark: _converse.removeBookmarkViaEvent,
addBookmark: _converse.addBookmarkViaEvent, addBookmark: _converse.addBookmarkViaEvent,
renderBookmarkListElement (item) { renderBookmarkListElement (chatbox) {
if (item instanceof _converse.ChatBox) { const bookmarkview = this.get(chatbox.get('jid'));
item = _.head(this.model.where({'jid': item.get('jid')})); if (_.isNil(bookmarkview)) {
if (_.isNil(item)) {
// A chat box has been closed, but we don't have a // A chat box has been closed, but we don't have a
// bookmark for it, so nothing further to do here. // bookmark for it, so nothing further to do here.
return; return;
} }
} bookmarkview.render();
if (_converse.hide_open_bookmarks && this.hideListIfEmpty();
_converse.chatboxes.where({'jid': item.get('jid')}).length) {
// A chat box has been opened, and we don't show
// bookmarks for open chats, so we remove it.
this.removeBookmarkListElement(item);
return;
}
const list_el = this.el.querySelector('.bookmarks');
const div = document.createElement('div');
div.innerHTML = tpl_bookmark({
'bookmarked': true,
'info_leave_room': __('Leave this room'),
'info_remove': __('Remove this bookmark'),
'info_remove_bookmark': __('Unbookmark this room'),
'info_title': __('Show more information on this room'),
'jid': item.get('jid'),
'name': item.get('name'),
'open_title': __('Click to open this room')
});
const el = _.head(sizzle(
`.available-chatroom[data-room-jid="${item.get('jid')}"]`,
list_el));
if (el) {
el.innerHTML = div.firstChild.innerHTML;
} else {
list_el.appendChild(div.firstChild);
}
this.show();
}, },
show () { hideListIfEmpty (item) {
u.showElement(this.el); const bookmarks = sizzle('.available-chatroom:not(.hidden)', this.el);
}, if (!this.model.models.length || !bookmarks.length) {
hide () {
u.hideElement(this.el); u.hideElement(this.el);
},
removeBookmarkListElement (item) {
const list_el = this.el.querySelector('.bookmarks');
const el = _.head(sizzle(`.available-chatroom[data-room-jid="${item.get('jid')}"]`, list_el));
if (el) {
list_el.removeChild(el);
}
if (list_el.childElementCount === 0) {
this.hide();
} }
}, },

View File

@ -1,8 +1,8 @@
<dd class="available-chatroom" data-room-jid="{{{o.jid}}}"> <dd class="available-chatroom {[ if (o.hidden) { ]} hidden {[ } ]}" data-room-jid="{{{o.jid}}}">
<a class="open-room" data-room-jid="{{{o.jid}}}" title="{{{o.open_title}}}" href="#">{{{o.name}}}</a> <a class="open-room" data-room-jid="{{{o.jid}}}" title="{{{o.open_title}}}" href="#">{{{o.name}}}</a>
<a class="right remove-bookmark icon-pushpin {[ if (o.bookmarked) { ]} button-on {[ } ]}" <a class="right remove-bookmark icon-pushpin {[ if (o.bookmarked) { ]} button-on {[ } ]}"
data-room-jid="{{{o.jid}}}" data-bookmark-name="{{{o.name}}}" data-room-jid="{{{o.jid}}}" data-bookmark-name="{{{o.name}}}"
title="{{{o.jinfo_remove_bookmark}}}" href="#">&nbsp;</a> title="{{{o.info_remove_bookmark}}}" href="#">&nbsp;</a>
<a class="right room-info icon-room-info" data-room-jid="{{{o.jid}}}" <a class="right room-info icon-room-info" data-room-jid="{{{o.jid}}}"
title="{{{o.info_title}}}" href="#">&nbsp;</a> title="{{{o.info_title}}}" href="#">&nbsp;</a>
</dd> </dd>