Commit 5bbe67fc authored by Weblate's avatar Weblate

Merge remote-tracking branch 'origin/master'

parents 75cf81db 03b9447f
......@@ -17,6 +17,10 @@ though they should be private._
### API changes
- New API method `_converse.disco.getIdentity` to check whether a JID has a given identity.
### New configuration settings
- New configuration setting [allow_public_bookmarks](https://conversejs.org/docs/html/configurations.html#allow-public-bookmarks)
## 3.3.2 (2018-01-29)
### Bugfixes
......
......@@ -118,6 +118,8 @@ allow_bookmarks
Enables/disables chatroom bookmarks functionality.
This setting is only applicable if the ``converse-bookmarks`` plugin is loaded.
See also: `allow_public_bookmarks`_
allow_chat_pending_contacts
---------------------------
......@@ -190,6 +192,24 @@ allow_otr
Allow Off-the-record encryption of single-user chat messages.
allow_public_bookmarks
----------------------
* Default: ``false``
Some XMPP servers don't support private PEP/PubSub nodes, as required for
private bookmarks and outlined in `XEP-0223 <https://xmpp.org/extensions/xep-0223.html>`_.
Even though Converse.js asks for the bookmarks to be kept private (via the
`<publish-options>` XML node), the server simply ignores the privacy settings
and publishes the node contents under the default privacy setting, which makes
the information available to all roster contacts.
If your your XMPP server does not support `XEP-0223`'s ``#publish-options``
feature and you don't mind that your room bookmarks are visible to all
contacts, then you can set this setting to ``true``. Otherwise you won't be
able to have any room bookmarks at all for an account on that XMPP server.
allow_registration
------------------
......
......@@ -419,7 +419,7 @@
expect(view).toBeDefined();
var $toolbar = $(view.el).find('ul.chat-toolbar');
expect($toolbar.length).toBe(1);
expect($toolbar.children('li').length).toBe(4);
expect($toolbar.children('li').length).toBe(3);
done();
}));
......
......@@ -3,6 +3,8 @@
} (this, function ($, jasmine, mock, converse, test_utils) {
var Strophe = converse.env.Strophe;
var b64_sha1 = converse.env.b64_sha1;
var $pres = converse.env.$pres;
var _ = converse.env._;
describe("A chatbox with an active OTR session", function() {
......@@ -13,28 +15,57 @@
test_utils.createContacts(_converse, 'current');
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid);
var view = _converse.chatboxviews.get(contact_jid);
var spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).not.toBe(null);
view.model.set('otr_status', 0);
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).not.toBe(null);
view.model.set('otr_status', 1);
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).toBe(null);
view.model.set('otr_status', 2);
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).toBe(null);
// XXX: We need to send a presence from the contact, so that we
// have a resource, that resource is then queried to see
// whether Strophe.NS.SPOILER is supported, in which case
// the spoiler button will appear.
var presence = $pres({
'from': contact_jid+'/phone',
'to': 'dummy@localhost'
});
_converse.connection._dataRecv(test_utils.createRequest(presence));
test_utils.openChatBoxFor(_converse, contact_jid);
view.model.set('otr_status', 3);
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).not.toBe(null);
done();
test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () {
var spoiler_toggle;
var view = _converse.chatboxviews.get(contact_jid);
spyOn(view, 'addSpoilerButton').and.callThrough();
view.model.set('otr_status', 1);
test_utils.waitUntil(function () {
return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
}).then(function () {
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).toBe(null);
view.model.set('otr_status', 3);
return test_utils.waitUntil(function () {
return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
});
}).then(function () {
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).not.toBe(null);
view.model.set('otr_status', 2);
return test_utils.waitUntil(function () {
return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
});
}).then(function () {
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).toBe(null);
view.model.set('otr_status', 4);
return test_utils.waitUntil(function () {
return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
});
}).then(function () {
spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
expect(spoiler_toggle).not.toBe(null);
done();
});
});
}));
});
......
This diff is collapsed.
......@@ -218,6 +218,7 @@
// configuration settings.
_converse.api.settings.update({
allow_bookmarks: true,
allow_public_bookmarks: false,
hide_open_bookmarks: true
});
// Promises exposed by this plugin
......@@ -540,7 +541,7 @@
const identity = args[0],
options_support = args[1];
if (_.isNil(identity) || !options_support.supported) {
if (_.isNil(identity) || (!options_support.supported && !_converse.allow_public_bookmarks)) {
_converse.emit('bookmarksInitialized');
return;
}
......
......@@ -22,6 +22,7 @@
"tpl!message",
"tpl!new_day",
"tpl!spinner",
"tpl!spoiler_button",
"tpl!spoiler_message",
"tpl!toolbar"
], factory);
......@@ -40,11 +41,12 @@
tpl_message,
tpl_new_day,
tpl_spinner,
tpl_spoiler_button,
tpl_spoiler_message,
tpl_toolbar
) {
"use strict";
const { $msg, Backbone, Strophe, _, b64_sha1, sizzle, moment } = converse.env;
const { $msg, Backbone, Promise, Strophe, _, b64_sha1, f, sizzle, moment } = converse.env;
const u = converse.env.utils;
const KEY = {
ENTER: 13,
......@@ -323,6 +325,7 @@
this.getToolbarOptions(options || {})
);
this.el.querySelector('.chat-toolbar').innerHTML = toolbar(options);
this.addSpoilerButton(options);
this.insertEmojiPicker();
return this;
},
......@@ -343,14 +346,40 @@
'label_spoiler_hint': __('Optional hint'),
'message_value': _.get(this.el.querySelector('.chat-textarea'), 'value'),
'show_send_button': _converse.show_send_button,
'show_spoiler_button': _converse.visible_toolbar_buttons.spoiler,
'show_textarea': true,
'show_toolbar': _converse.show_toolbar,
'unread_msgs': __('You have unread messages')
}));
this.renderToolbar();
},
addSpoilerButton (options) {
/* Asynchronously adds a button for writing spoiler
* messages, based on whether the contact's client supports
* it.
*/
if (!options.show_spoiler_button || this.model.get('type') === 'chatroom') {
return;
}
const contact_jid = this.model.get('jid');
const resources = this.model.get('resources');
if (_.isEmpty(resources)) {
return;
}
Promise.all(_.map(_.keys(resources), (resource) =>
_converse.api.disco.supports(Strophe.NS.SPOILER, `${contact_jid}/${resource}`)
)).then((results) => {
const supported = _.every(f.map(f.get('supported'))(results));
if (supported) {
const html = tpl_spoiler_button(this.model.toJSON());
if (_converse.visible_toolbar_buttons.emoji) {
this.el.querySelector('.toggle-smiley').insertAdjacentHTML('afterEnd', html);
} else {
this.el.querySelector('.chat-toolbar').insertAdjacentHTML('afterBegin', html);
}
}
});
},
insertHeading () {
this.heading = new _converse.ChatBoxHeading({'model': this.model});
this.heading.render();
......
......@@ -451,6 +451,8 @@
_converse.LoginPanelModel = Backbone.Model.extend({
defaults: {
// Passed-by-reference. Fine in this case because there's
// only one such model.
'errors': [],
}
});
......
......@@ -9,6 +9,7 @@
define(["sizzle",
"es6-promise",
"lodash.noconflict",
"lodash.fp",
"polyfill",
"i18n",
"utils",
......@@ -19,7 +20,7 @@
"backbone.nativeview",
"backbone.browserStorage"
], factory);
}(this, function (sizzle, Promise, _, polyfill, i18n, utils, moment, Strophe, pluggable, Backbone) {
}(this, function (sizzle, Promise, _, f, polyfill, i18n, utils, moment, Strophe, pluggable, Backbone) {
/* Cannot use this due to Safari bug.
* See https://github.com/jcbrand/converse.js/issues/196
......@@ -857,10 +858,8 @@
this.RosterContact = Backbone.Model.extend({
defaults: {
'bookmarked': false,
'chat_state': undefined,
'chat_status': 'offline',
'groups': [],
'image': _converse.DEFAULT_IMAGE,
'image_type': _converse.DEFAULT_IMAGE_TYPE,
'num_unread': 0,
......@@ -873,11 +872,12 @@
const resource = Strophe.getResourceFromJid(jid);
attributes.jid = bare_jid;
this.set(_.assignIn({
'fullname': bare_jid,
'groups': [],
'id': bare_jid,
'jid': bare_jid,
'fullname': bare_jid,
'user_id': Strophe.getNodeFromJid(jid),
'resources': resource ? {resource :0} : {},
'resources': {},
'user_id': Strophe.getNodeFromJid(jid)
}, attributes));
this.on('destroy', () => { this.removeFromRoster(); });
......@@ -973,6 +973,7 @@
const resources = _.isObject(this.get('resources')) ? this.get('resources') : {};
resources[resource] = {
'name': resource,
'priority': priority,
'status': chat_status,
'timestamp': timestamp
......@@ -2020,6 +2021,7 @@
'Promise': Promise,
'Strophe': Strophe,
'_': _,
'f': f,
'b64_sha1': b64_sha1,
'moment': moment,
'sizzle': sizzle,
......
......@@ -146,8 +146,7 @@
}
function registerHeadlineHandler () {
_converse.connection.addHandler(
onHeadlineMessage, null, 'message');
_converse.connection.addHandler(onHeadlineMessage, null, 'message');
}
_converse.on('connected', registerHeadlineHandler);
_converse.on('reconnected', registerHeadlineHandler);
......
......@@ -83,7 +83,7 @@
}
const messages = [];
const message_handler = _converse.connection.addHandler(function (message) {
const message_handler = _converse.connection.addHandler((message) => {
if (options.groupchat && message.getAttribute('from') !== options['with']) { // eslint-disable-line dot-notation
return true;
}
......
define(['lodash', 'lodash.converter', 'converse-core'], function (_, lodashConverter, converse) {
define(['lodash', 'lodash.converter'], function (_, lodashConverter) {
var fp = lodashConverter(_.runInContext());
converse.env.fp = fp;
return fp;
});
{[ if (o.show_spoiler_button) { ]}
<!-- XXX: This markup is also in src/templates/toolbar.html -->
<li class="toggle-compose-spoiler">
<a class="
{[ if (o.sending_spoiler) { ]} icon-eye-blocked {[ } ]}
{[ if (!o.sending_spoiler) { ]} icon-eye {[ } ]}"
title="{{ o.title }}"></a>
{[ if (o.composing_spoiler) { ]} icon-eye-blocked {[ } ]}
{[ if (!o.composing_spoiler) { ]} icon-eye {[ } ]}"
title="{{ o.label_toggle_spoiler }}"></a>
</li>
{[ } ]}
......@@ -4,14 +4,6 @@
<span class="emoji-picker"></span>
</li>
{[ } ]}
{[ if (o.show_spoiler_button) { ]}
<li class="toggle-compose-spoiler">
<a class="
{[ if (o.composing_spoiler) { ]} icon-eye-blocked {[ } ]}
{[ if (!o.composing_spoiler) { ]} icon-eye {[ } ]}"
title="{{ o.label_toggle_spoiler }}"></a>
</li>
{[ } ]}
{[ if (o.show_call_button) { ]}
<li class="toggle-call"><a class="icon-phone" title="{{{o.label_start_call}}}"></a></li>
{[ } ]}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment