From 38f8724dd9501aa236c8102ed836bd56f344fe66 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Wed, 9 Aug 2017 15:50:24 +0200 Subject: [PATCH] roomslist: Add ability to add or remove bookmarks --- CHANGES.md | 31 ++++++++++++----------- css/converse.css | 6 +++++ css/inverse.css | 6 +++++ docs/source/configuration.rst | 4 +-- docs/source/plugin_development.rst | 4 ++- sass/_controlbox.scss | 1 + src/converse-bookmarks.js | 40 ++++++++++++++++++++++-------- src/converse-muc.js | 16 ++++++------ src/converse-roomslist.js | 23 ++++++++++++++++- src/templates/rooms_list_item.html | 5 ++-- 10 files changed, 97 insertions(+), 39 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 455e50b78..6cb7a6240 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,12 +5,12 @@ ### New Plugins - New plugin `converse-disco` which replaces the original support for [XEP-0030](https://xmpp.org/extensions/xep-0030.html) and which has been - refactored to allow features for multiple entities to be stored. [jcbrand] + refactored to allow features for multiple entities to be stored. ### New features and improvements -- Add support for Emojis (either native, or via Emojione). [jcbrand] -- Add JID validation to the contact add form, the occupant invite form and the login form. [jcbrand] -- #896 Consistently use `XMPP username` in user-facing text (instead of JID, Jabber ID etc.). [jcbrand] +- Add support for Emojis (either native, or via Emojione). +- Add JID validation to the contact add form, the occupant invite form and the login form. +- #896 Consistently use `XMPP username` in user-facing text (instead of JID, Jabber ID etc.). ### New configuration settings * The `visible_toolbar_buttons.emoticons` configuration option is now changed to `visible_toolbar_buttons.emoji`. @@ -25,20 +25,21 @@ * ['afterMessagesFetched'](https://conversejs.org/docs/html/development.html#afterMessagesFetched) ### Code changes -- Removed jQuery from `converse-core`, `converse-vcard` and `converse-roomslist`. [jcbrand] +- Removed jQuery from `converse-core`, `converse-vcard` and `converse-roomslist`. - Remove `jquery.easing` from the full build. Was only being used by the - [conversejs.org](https://conversejs.org) website, which has been updated to not rely on it. [jcbrand] -- All promises are now native (or polyfilled) ES2015 Promises instead of jQuery's Deferred. [jcbrand] -- #866 Add babel in order to support ES2015 syntax [jcbrand] + [conversejs.org](https://conversejs.org) website, which has been updated to not rely on it. +- All promises are now native (or polyfilled) ES2015 Promises instead of jQuery's Deferred. +- #866 Add babel in order to support ES2015 syntax #### Bugfixes: -- The domain was queried for MAM:2 support, instead of the JID. [jcbrand] -- Roster filter is not shown when all groups are collapsed. [jcbrand] -- When filtering, contacts in closed groups appear. [jcbrand] -- Room name wasn't being updated after changing it in the configuration form. [jcbrand] -- Server disco features were "forgotten" after logging out and then logging in again. [jcbrand] -- Don't show duplicate sent groupchat messages in Slack chat rooms. [jcbrand] -- Bookmark icon shown in the open rooms list when `allow_bookmarks` is to `false`. [jcbrand] +- The domain was queried for MAM:2 support, instead of the JID. +- Roster filter is not shown when all groups are collapsed. +- When filtering, contacts in closed groups appear. +- Room name wasn't being updated after changing it in the configuration form. +- Server disco features were "forgotten" after logging out and then logging in again. +- Don't show duplicate sent groupchat messages in Slack chat rooms. +- Bookmark icon shown in the open rooms list when `allow_bookmarks` is to `false`. +- It wasn't possible to add or remove bookmarks via the "Open Rooms" list. - #879 Text in links are converted to smileys leading to non-clickable links. ## 3.1.1 (2017-07-12) diff --git a/css/converse.css b/css/converse.css index 24e859f07..822016350 100644 --- a/css/converse.css +++ b/css/converse.css @@ -2039,13 +2039,19 @@ #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom a.available-room, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom a.available-room { width: 85%; } + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .add-bookmark, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .remove-bookmark, + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .add-bookmark, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .remove-bookmark { color: #A8ABA1; } + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .add-bookmark.button-on, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .remove-bookmark.button-on, + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .add-bookmark.button-on, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .remove-bookmark.button-on { color: #578EA9; } + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .add-bookmark.button-on:hover, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .remove-bookmark.button-on:hover, + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .add-bookmark.button-on:hover, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .remove-bookmark.button-on:hover { color: #206485; } #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .room-info, diff --git a/css/inverse.css b/css/inverse.css index dd624ea09..b2fe954ca 100644 --- a/css/inverse.css +++ b/css/inverse.css @@ -2105,13 +2105,19 @@ body { #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom a.available-room, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom a.available-room { width: 85%; } + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .add-bookmark, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .remove-bookmark, + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .add-bookmark, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .remove-bookmark { color: #A8ABA1; } + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .add-bookmark.button-on, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .remove-bookmark.button-on, + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .add-bookmark.button-on, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .remove-bookmark.button-on { color: #578EA9; } + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .add-bookmark.button-on:hover, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .remove-bookmark.button-on:hover, + #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .add-bookmark.button-on:hover, #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .open-chatroom .remove-bookmark.button-on:hover { color: #206485; } #conversejs #controlbox #chatrooms .rooms-list-container dl.rooms-list .available-chatroom .room-info, diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index 7d2fc93d5..7026c62b9 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -19,7 +19,7 @@ on your website. You'll most likely want to call the *initialize* method in your HTML page. For an example of how this is done, please see the bottom of the *./index.html* page. -Please refer to the `Configuration variables`_ section below for info on +Please refer to the `Configuration settings`_ section below for info on all the available configuration settings. After you have configured *Converse.js*, you'll have to regenerate the minified @@ -1109,7 +1109,7 @@ loaded), then an error will be raised. Otherwise a message will simply be logged and the override instruction ignored. -The Converse.js plugins architecture can have an ``optional_dependencies`` +The Converse.js plugins architecture can have an :ref:`optional_dependencies` plugin attribute. This enables you to specify an array of optional, or "soft", dependencies. Converse.js (more specifically, `pluggable.js `_) will try to first diff --git a/docs/source/plugin_development.rst b/docs/source/plugin_development.rst index 3a2243e1a..df4a5cf6e 100644 --- a/docs/source/plugin_development.rst +++ b/docs/source/plugin_development.rst @@ -167,6 +167,8 @@ A better approach is to listen to the events emitted by Converse.js, and to add your code in event handlers. This is however not always possible, in which case the overrides are a powerful tool. +.. _`optional_dependencies`: + Optional plugin dependencies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -189,7 +191,7 @@ In this case, you can't specify the plugin as a dependency in the ``define`` statement at the top of the plugin, since it might not always be available, which would cause ``require.js`` to throw an error. -To resolve this problem we thave the ``optional_dependencies`` Array attribute. +To resolve this problem we have the ``optional_dependencies`` Array attribute. With this you can specify those dependencies which need to be loaded before your plugin, if they exist. If they don't exist, they won't be ignored. diff --git a/sass/_controlbox.scss b/sass/_controlbox.scss index 25667cc80..3bdd2fedb 100644 --- a/sass/_controlbox.scss +++ b/sass/_controlbox.scss @@ -191,6 +191,7 @@ width: 85%; } } + .add-bookmark, .remove-bookmark { &.button-on { color: $link-color; diff --git a/src/converse-bookmarks.js b/src/converse-bookmarks.js index d036c9491..d52db708d 100644 --- a/src/converse-bookmarks.js +++ b/src/converse-bookmarks.js @@ -198,6 +198,31 @@ // Promises exposed by this plugin _converse.api.promises.add('bookmarksInitialized'); + // Pure functions on the _converse object + _.extend(_converse, { + removeBookmarkViaEvent (ev) { + /* Remove a bookmark as determined by the passed in + * event. + */ + ev.preventDefault(); + const name = ev.target.getAttribute('data-bookmark-name'); + const jid = ev.target.getAttribute('data-room-jid'); + if (confirm(__(___("Are you sure you want to remove the bookmark \"%1$s\"?"), name))) { + _.invokeMap(_converse.bookmarks.where({'jid': jid}), Backbone.Model.prototype.destroy); + } + }, + + addBookmarkViaEvent (ev) { + /* Add a bookmark as determined by the passed in + * event. + */ + ev.preventDefault(); + const jid = ev.target.getAttribute('data-room-jid'); + const chatroom = _converse.openChatRoom({'jid': jid}, true); + _converse.chatboxviews.get(jid).renderBookmarkForm(); + }, + }); + _converse.Bookmark = Backbone.Model; _converse.BookmarksList = Backbone.Model.extend({ @@ -353,8 +378,9 @@ tagName: 'div', className: 'bookmarks-list, rooms-list-container', events: { - 'click .remove-bookmark': 'removeBookmark', - 'click .bookmarks-toggle': 'toggleBookmarksList' + 'click .add-bookmark': 'addBookmark', + 'click .bookmarks-toggle': 'toggleBookmarksList', + 'click .remove-bookmark': 'removeBookmark' }, initialize () { @@ -390,14 +416,8 @@ return this.$el; }, - removeBookmark (ev) { - ev.preventDefault(); - const name = $(ev.target).data('bookmarkName'); - const jid = $(ev.target).data('roomJid'); - if (confirm(__(___("Are you sure you want to remove the bookmark \"%1$s\"?"), name))) { - _.invokeMap(_converse.bookmarks.where({'jid': jid}), Backbone.Model.prototype.destroy); - } - }, + removeBookmark: _converse.removeBookmarkViaEvent, + addBookmark: _converse.addBookmarkViaEvent, renderBookmarkListElement (item) { if (item instanceof _converse.ChatBox) { diff --git a/src/converse-muc.js b/src/converse-muc.js index 0b06d3298..6027e39e7 100755 --- a/src/converse-muc.js +++ b/src/converse-muc.js @@ -339,13 +339,18 @@ }); _converse.api.promises.add('roomsPanelRendered'); - _converse.openChatRoom = function (settings) { + _converse.openChatRoom = function (settings, bring_to_foreground) { /* Opens a chat room, making sure that certain attributes * are correct, for example that the "type" is set to * "chatroom". */ - settings.type = CHATROOMS_TYPE - return _converse.chatboxviews.showChat(settings); + if (_.isUndefined(settings.jid)) { + throw new Error("openChatRoom needs to be called with a JID"); + } + settings.type = CHATROOMS_TYPE; + settings.id = settings.jid; + settings.box_id = b64_sha1(settings.jid) + return _converse.chatboxviews.showChat(settings, bring_to_foreground); }; _converse.ChatRoom = _converse.ChatBox.extend({ @@ -2619,11 +2624,8 @@ } } return { - 'id': jid, 'jid': jid, 'name': name || Strophe.unescapeNode(Strophe.getNodeFromJid(jid)), - 'type': CHATROOMS_TYPE, - 'box_id': b64_sha1(jid) } }, @@ -2681,9 +2683,7 @@ } if (result === true) { const chatroom = _converse.openChatRoom({ - 'id': room_jid, 'jid': room_jid, - 'box_id': b64_sha1(room_jid), 'password': $x.attr('password') }); if (chatroom.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED) { diff --git a/src/converse-roomslist.js b/src/converse-roomslist.js index 01f9219f6..424ee2d80 100644 --- a/src/converse-roomslist.js +++ b/src/converse-roomslist.js @@ -20,6 +20,21 @@ const { Backbone, Promise, b64_sha1, sizzle, _ } = converse.env; converse.plugins.add('converse-roomslist', { + + /* Optional dependencies are other plugins which might be + * overridden or relied upon, and therefore need to be loaded before + * this plugin. They are called "optional" because they might not be + * available, in which case any overrides applicable to them will be + * ignored. + * + * It's possible however to make optional dependencies non-optional. + * If the setting "strict_plugin_dependencies" is set to true, + * an error will be raised if the plugin is not found. + * + * NB: These plugins need to have already been loaded via require.js. + */ + optional_dependencies: ["converse-bookmarks"], + initialize () { /* The initialize function gets called as soon as the plugin is * loaded by converse.js's plugin machinery. @@ -37,8 +52,10 @@ tagName: 'div', className: 'open-rooms-list rooms-list-container', events: { + 'click .add-bookmark': 'addBookmark', 'click .close-room': 'closeRoom', - 'click .open-rooms-toggle': 'toggleRoomsList' + 'click .open-rooms-toggle': 'toggleRoomsList', + 'click .remove-bookmark': 'removeBookmark', }, initialize () { @@ -120,6 +137,7 @@ 'allow_bookmarks': _converse.allow_bookmarks, 'info_leave_room': __('Leave this room'), 'info_remove_bookmark': __('Unbookmark this room'), + 'info_add_bookmark': __('Bookmark this room'), 'info_title': __('Show more information on this room'), 'name': name, 'open_title': __('Click to open this room') @@ -128,6 +146,9 @@ this.show(); }, + removeBookmark: _converse.removeBookmarkViaEvent, + addBookmark: _converse.addBookmarkViaEvent, + removeRoomsListElement (item) { const list_el = this.el.querySelector('.open-rooms-list'); const el = _.head(sizzle(`.available-chatroom[data-room-jid="${item.get('jid')}"]`, list_el)); diff --git a/src/templates/rooms_list_item.html b/src/templates/rooms_list_item.html index 76de90f06..22d632100 100644 --- a/src/templates/rooms_list_item.html +++ b/src/templates/rooms_list_item.html @@ -11,9 +11,10 @@ title="{{{info_leave_room}}}" href="#">  {[ if (allow_bookmarks) { ]} -  + title="{[ if (bookmarked) { ]} {{{info_remove_bookmark}}} {[ } else { ]} {{{info_add_bookmark}}} {[ } ]}" + href="#">  {[ } ]}