Initial work on showing open rooms in the "Rooms" panel

This commit is contained in:
JC Brand 2017-04-29 13:30:47 +02:00
parent d8963a8a8c
commit 70e4f28548
15 changed files with 328 additions and 151 deletions

View File

@ -228,7 +228,7 @@
content: "\2b25"; }
#converse-embedded-chat .icon-remove:before,
#conversejs .icon-remove:before {
content: "\e02d"; }
content: "\2715"; }
#converse-embedded-chat .icon-room-info:before,
#conversejs .icon-room-info:before {
content: "\e059"; }
@ -1328,7 +1328,7 @@
#converse-embedded-chat form.pure-form.converse-form,
#conversejs form.pure-form.converse-form {
background: white;
padding: 1em; }
padding: 0 1em; }
#converse-embedded-chat form.pure-form.converse-form legend,
#conversejs form.pure-form.converse-form legend {
color: #818479; }
@ -1889,51 +1889,63 @@
#conversejs #controlbox #chatrooms form.add-chatroom input[type=submit],
#conversejs #controlbox #chatrooms form.add-chatroom input[type=text] {
width: 100%; }
#conversejs #controlbox #chatrooms dl.rooms-list {
margin: 0 1em;
padding: 0;
text-align: left; }
#conversejs #controlbox #chatrooms dl.rooms-list dt {
border: none;
color: #818479;
font-weight: normal;
padding: 0;
padding-bottom: 0.5em;
text-shadow: 0 1px 0 #FAFAFA; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom {
border: none;
clear: both;
color: #818479;
#conversejs #controlbox #chatrooms .rooms-list-container {
text-align: left;
margin: 0 1em; }
#conversejs #controlbox #chatrooms .rooms-list-container .rooms-toggle {
display: block;
overflow: hidden;
padding: 0.1em;
text-shadow: 0 1px 0 #FAFAFA;
word-wrap: break-word; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom:hover {
background-color: #DCF9F6; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom a.room-info {
clear: right;
display: block; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom a.room-info:before {
font-size: 15px; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom a.open-room {
float: left;
width: 85%; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom .room-info {
font-size: 12px;
font-style: normal;
font-weight: normal; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom li.room-info {
display: block;
margin-left: 5px; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom p.room-info {
margin: 0;
font-weight: bold;
color: #818479;
margin-top: 1em; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list {
margin: 0.5em 0;
text-align: left; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dt {
border: none;
color: #818479;
font-weight: normal;
padding: 0;
padding-bottom: 0.5em;
text-shadow: 0 1px 0 #FAFAFA; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom {
border: none;
clear: both;
color: #818479;
display: block;
white-space: normal; }
#conversejs #controlbox #chatrooms dl.rooms-list dd.available-chatroom div.room-info {
clear: left;
width: 100%; }
overflow: hidden;
padding: 0.3em 0;
text-shadow: 0 1px 0 #FAFAFA;
word-wrap: break-word; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom:hover {
background-color: #DCF9F6; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom a.room-info:before {
font-size: 15px; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom a.open-room {
float: left;
width: 68%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 0.5em; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom .remove-bookmark {
color: #BBB; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom .remove-bookmark.button-on {
color: #2A9D8F; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom .room-info {
font-size: 12px;
font-style: normal;
font-weight: normal; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom li.room-info {
display: block;
margin-left: 5px; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom p.room-info {
margin: 0;
padding: 0;
display: block;
white-space: normal; }
#conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list dd.available-chatroom div.room-info {
clear: left;
width: 100%; }
#conversejs #controlbox .dropdown {
/* Custom addition for CSP */ }
#conversejs #controlbox .dropdown a {
@ -2356,7 +2368,7 @@
float: right;
margin-right: 1em;
padding-top: 0.5em;
color: #A8ABA1; }
color: #BBB; }
#conversejs #converse-roster span.pending-contact-name {
line-height: 16px;
width: 100%; }
@ -2628,24 +2640,6 @@
#conversejs #minimized-chats .chat-head-message-count-hidden {
display: none; }
#conversejs #controlbox #chatrooms .bookmarks-list {
padding-top: 1em; }
#conversejs #controlbox #chatrooms .bookmarks-list .bookmarks-toggle {
display: block;
font-weight: bold;
color: #818479;
margin-bottom: 0.5em; }
#conversejs #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.room-info {
clear: none; }
#conversejs #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room {
width: 75%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 0.5em; }
#conversejs #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom .remove-bookmark {
float: right; }
#converse-embedded-chat,
#conversejs {
/* Pointer */ }

View File

@ -6,13 +6,13 @@
one chat is visible at any given time. Used in the mobile build:
`converse-mobile.js` and makes the unread messages counter possible there.
[jcbrand]
- Show unread messages next to roster contacts. [jcbrand]
- API change: the `message` event now returns a data object with `stanza` and
`chatbox` attributes, instead of just the stanza. [jcbrand]
- Remove all inline CSS to comply with strict Content-Security-Policy headers [mathiasertl]
- #567 Unreaded message count reset on page load [novokrest]
- #591 Unread message counter is reset when the chatbox is closed [novokrest]
- #754 Show unread messages next to roster contacts. [jcbrand]
- #873 Inconsistent unread messages count updating [novokrest]
- Remove all inline CSS to comply with strict Content-Security-Policy headers [mathiasertl]
## 3.0.2 (2017-04-23)

View File

@ -2,33 +2,6 @@
#controlbox {
#chatrooms {
.bookmarks-list {
padding-top: 1em;
.bookmarks-toggle {
display: block;
font-weight: bold;
color: $text-color;
margin-bottom: 0.5em;
}
dl.rooms-list.bookmarks {
dd.available-chatroom {
a {
&.room-info {
clear: none;
}
&.open-room {
width: 75%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 0.5em;
}
}
.remove-bookmark {
float: right;
}
}
}
}
}
}

View File

@ -114,61 +114,78 @@
width: 100%;
}
}
dl.rooms-list {
margin: 0 1em;
padding: 0;
.rooms-list-container {
text-align: left;
dt {
border: none;
color: $text-color;
font-weight: normal;
padding: 0;
padding-bottom: 0.5em;
text-shadow: 0 1px 0 $text-shadow-color;
}
dd.available-chatroom {
border: none;
clear: both;
color: $text-color;
margin: 0 1em;
.rooms-toggle {
display: block;
overflow: hidden;
padding: 0.1em;
text-shadow: 0 1px 0 $text-shadow-color;
word-wrap: break-word;
&:hover {
background-color: $highlight-color;
font-weight: bold;
color: $text-color;
margin-top: 1em;
}
dl.rooms-list {
margin: 0.5em 0;
text-align: left;
dt {
border: none;
color: $text-color;
font-weight: normal;
padding: 0;
padding-bottom: 0.5em;
text-shadow: 0 1px 0 $text-shadow-color;
}
a {
&.room-info {
clear: right;
display: block;
&:before {
font-size: 15px;
dd.available-chatroom {
border: none;
clear: both;
color: $text-color;
display: block;
overflow: hidden;
padding: 0.3em 0;
text-shadow: 0 1px 0 $text-shadow-color;
word-wrap: break-word;
&:hover {
background-color: $highlight-color;
}
a {
&.room-info {
&:before {
font-size: 15px;
}
}
&.open-room {
float: left;
width: 68%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 0.5em;
}
}
&.open-room {
float: left;
width: 85%;
.remove-bookmark {
&.button-on {
color: $link-color;
}
color: $subdued-color;
}
.room-info {
font-size: $font-size-small;
font-style: normal;
font-weight: normal;
}
li.room-info {
display: block;
margin-left: 5px;
}
p.room-info {
margin: 0;
padding: 0;
display: block;
white-space: normal;
}
div.room-info {
clear: left;
width: 100%;
}
}
.room-info {
font-size: $font-size-small;
font-style: normal;
font-weight: normal;
}
li.room-info {
display: block;
margin-left: 5px;
}
p.room-info {
margin: 0;
padding: 0;
display: block;
white-space: normal;
}
div.room-info {
clear: left;
width: 100%;
}
}
}

View File

@ -170,7 +170,7 @@
form {
&.pure-form.converse-form {
background: white;
padding: 1em;
padding: 0 1em;
legend {
color: $text-color;
}

View File

@ -93,7 +93,7 @@
.icon-quotes-left:before { content: "\e01d"; }
.icon-radio-checked:before { content: "\2b26"; }
.icon-radio-unchecked:before { content: "\2b25"; }
.icon-remove:before { content: "\e02d"; }
.icon-remove:before { content: "\2715"; }
.icon-room-info:before { content: "\e059"; }
.icon-sad:before { content: "\2639"; }
.icon-save:before { content: "\f0c7"; }

View File

@ -43,7 +43,7 @@ $toolbar-color: #FFF5EE !default;
$moderator-color: #D24E2B !default;
$online-color: #1A9707 !default;
$error-color: #D24E2B !default;
$subdued-color: #A8ABA1 !default;
$subdued-color: #BBB !default;
$chatbox-border-radius: 4px !default;
$bottom-gutter-height: 35px !default;

View File

@ -59,6 +59,7 @@ require.config({
"converse-otr": "src/converse-otr",
"converse-ping": "src/converse-ping",
"converse-register": "src/converse-register",
"converse-roomslist": "src/converse-roomslist",
"converse-rosterview": "src/converse-rosterview",
"converse-singleton": "src/converse-singleton",
"converse-vcard": "src/converse-vcard",
@ -149,6 +150,7 @@ require.config({
"room_description": "src/templates/room_description",
"room_item": "src/templates/room_item",
"room_panel": "src/templates/room_panel",
"rooms_list": "src/templates/rooms_list",
"roster": "src/templates/roster",
"roster_filter": "src/templates/roster_filter",
"roster_item": "src/templates/roster_item",

View File

@ -10,7 +10,7 @@
* in XEP-0048.
*/
(function (root, factory) {
define([ "utils",
define(["utils",
"converse-core",
"converse-muc",
"tpl!chatroom_bookmark_form",
@ -352,7 +352,7 @@
_converse.BookmarksView = Backbone.View.extend({
tagName: 'div',
className: 'bookmarks-list',
className: 'bookmarks-list, rooms-list-container',
events: {
'click .remove-bookmark': 'removeBookmark',
'click .bookmarks-toggle': 'toggleBookmarksList'
@ -378,7 +378,7 @@
this.$el.html(tpl_bookmarks_list({
'toggle_state': this.list_model.get('toggle-state'),
'desc_bookmarks': __('Click to toggle the bookmarks list'),
'label_bookmarks': __('Bookmarked Rooms')
'label_bookmarks': __('Bookmarks')
})).hide();
if (this.list_model.get('toggle-state') !== _converse.OPENED) {
this.$('.bookmarks').hide();
@ -470,7 +470,7 @@
});
_converse.emit('bookmarksInitialized');
};
_converse.on('chatBoxesFetched', initBookmarks);
_converse.on('roomsPanelRendered', initBookmarks);
var afterReconnection = function () {
if (!_converse.allow_bookmarks) {

186
src/converse-roomslist.js Normal file
View File

@ -0,0 +1,186 @@
// Converse.js (A browser based XMPP chat client)
// http://conversejs.org
//
// Copyright (c) 2012-2017, Jan-Carel Brand <jc@opkode.com>
// Licensed under the Mozilla Public License (MPLv2)
//
/*global define */
/* This is a non-core Converse.js plugin which shows a list of currently open
* rooms in the "Rooms Panel" of the ControlBox.
*/
(function (root, factory) {
define(["utils",
"converse-core",
"converse-muc",
"tpl!bookmark",
"tpl!rooms_list"
], factory);
}(this, function (utils, converse, muc, tpl_bookmark, tpl_rooms_list) {
var $ = converse.env.jQuery,
Backbone = converse.env.Backbone,
b64_sha1 = converse.env.b64_sha1,
sizzle = converse.env.sizzle,
_ = converse.env._;
converse.plugins.add('converse-roomslist', {
initialize: function () {
/* The initialize function gets called as soon as the plugin is
* loaded by converse.js's plugin machinery.
*/
var _converse = this._converse,
__ = _converse.__,
___ = _converse.___;
_converse.RoomsList = Backbone.Model.extend({
defaults: {
"toggle-state": _converse.OPENED
},
initialize: function () {
}
});
_converse.RoomsListView = Backbone.View.extend({
tagName: 'div',
className: 'open-rooms-list, rooms-list-container',
events: {
'click .close-room': 'closeRoom',
'click .open-rooms-toggle': 'toggleRoomsList'
},
initialize: function () {
this.model.on('add', this.renderRoomsListElement, this);
this.model.on('change:bookmarked', this.renderRoomsListElement, this);
this.model.on('change:name', this.renderRoomsListElement, this);
this.model.on('remove', this.removeRoomsListElement, this);
var cachekey = 'converse.roomslist'+_converse.bare_jid;
this.list_model = new _converse.RoomsList();
this.list_model.id = cachekey;
this.list_model.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1(cachekey)
);
this.list_model.fetch();
this.render();
},
render: function () {
this.el.innerHTML =
tpl_rooms_list({
'toggle_state': this.list_model.get('toggle-state'),
'desc_rooms': __('Click to toggle the rooms list'),
'label_rooms': __('Open Rooms')
})
this.hide();
if (this.list_model.get('toggle-state') !== _converse.OPENED) {
this.$('.open-rooms-list').hide();
}
this.model.each(this.renderRoomsListElement.bind(this));
var controlboxview = _converse.chatboxviews.get('controlbox');
if (!_.isUndefined(controlboxview) &&
!document.body.contains(this.el)) {
var container = controlboxview.el.querySelector('#chatrooms');
if (!_.isNull(container)) {
container.insertBefore(this.el, container.firstChild);
}
}
return this.el;
},
hide: function () {
this.el.classList.add('hidden');
},
show: function () {
this.el.classList.remove('hidden');
},
closeRoom: function (ev) {
ev.preventDefault();
var name = $(ev.target).data('roomName');
var jid = $(ev.target).data('roomJid');
if (confirm(__(___("Are you sure you want to leave the room \"%1$s\"?"), name))) {
_converse.chatboxviews.get(jid).leave();
}
},
renderRoomsListElement: function (item) {
if (item.get('type') !== 'chatroom') {
return;
}
this.removeRoomsListElement(item);
var name, bookmark
if (item.get('bookmarked')) {
bookmark = _.head(_converse.bookmarksview.model.where({'jid': item.get('jid')}));
name = bookmark.get('name');
} else {
name = item.get('name');
}
var div = document.createElement('div');
div.innerHTML = tpl_bookmark(_.extend(item.toJSON(), {
'can_leave_room': true,
'info_leave_room': __('Leave this room'),
'info_remove_bookmark': __('Unbookmark this room'),
'info_title': __('Show more information on this room'),
'name': name,
'open_title': __('Click to open this room')
}));
this.el.querySelector('.open-rooms-list').appendChild(div.firstChild);
this.show();
},
removeRoomsListElement: function (item) {
var list_el = this.el.querySelector('.open-rooms-list');
var 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();
}
},
toggleRoomsList: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var el = ev.target;
if (el.classList.contains("icon-opened")) {
this.$('.open-rooms-list').slideUp('fast');
this.list_model.save({'toggle-state': _converse.CLOSED});
el.classList.remove("icon-opened");
el.classList.add("icon-closed");
} else {
el.classList.remove("icon-closed");
el.classList.add("icon-opened");
this.$('.open-rooms-list').slideDown('fast');
this.list_model.save({'toggle-state': _converse.OPENED});
}
}
});
var initRoomsListView = function () {
_converse.rooms_list_view = new _converse.RoomsListView(
{'model': _converse.chatboxes}
);
};
_converse.on('bookmarksInitialized', initRoomsListView);
_converse.on('roomsPanelRendered', function () {
if (_converse.allow_bookmarks) {
return;
}
initRoomsListView();
});
var afterReconnection = function () {
if (_.isUndefined(_converse.rooms_list_view)) {
initRoomsListView();
} else {
_converse.rooms_list_view.render();
}
};
_converse.on('reconnected', afterReconnection);
}
});
}));

View File

@ -14,6 +14,7 @@ if (typeof define !== 'undefined') {
"converse-chatview", // Renders standalone chat boxes for single user chat
"converse-controlbox", // The control box
"converse-bookmarks", // XEP-0048 Bookmarks
"converse-roomslist", // XEP-0048 Bookmarks
"converse-mam", // XEP-0313 Message Archive Management
"converse-muc", // XEP-0045 Multi-user chat
"converse-vcard", // XEP-0054 VCard-temp

View File

@ -1,7 +1,7 @@
<dd class="available-chatroom" data-room-jid="{{{jid}}}">
<a class="open-room" data-room-jid="{{{jid}}}" title="{{{open_title}}}" href="#">{{{name}}}</a>
{[ if (can_leave_room) { ]}
<a class="right remove-room icon-remove"
<a class="right close-room icon-remove"
data-room-jid="{{{jid}}}" title="{{{info_leave_room}}}" href="#">&nbsp;</a>
{[ } ]}
<a class="right remove-bookmark icon-pushpin {[ if (bookmarked) { ]} button-on {[ } ]}"

View File

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

View File

@ -10,4 +10,6 @@
<input type="button" class="pure-button button-secondary" name="show" id="show-rooms" value="{{label_show_rooms}}"/>
</fieldset>
</form>
<dl id="available-chatrooms" class="rooms-list"></dl>
<div class="rooms-list-container">
<dl id="available-chatrooms" class="rooms-list"></dl>
</div>

View File

@ -0,0 +1,2 @@
<a href="#" class="rooms-toggle open-rooms-toggle icon-{{{toggle_state}}}" title="{{{desc_rooms}}}">{{{label_rooms}}}</a>
<dl class="rooms-list open-rooms-list"></dl>