Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
d3a45551
Commit
d3a45551
authored
Feb 26, 2019
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Re-add support for `muc_domain` and add `locked_muc_domain`.
updates #1373
parent
2ddd918f
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
283 additions
and
34 deletions
+283
-34
CHANGES.md
CHANGES.md
+3
-1
dist/converse.js
dist/converse.js
+55
-12
docs/source/configuration.rst
docs/source/configuration.rst
+24
-5
spec/muc.js
spec/muc.js
+159
-7
src/converse-muc-views.js
src/converse-muc-views.js
+39
-7
src/headless/converse-muc.js
src/headless/converse-muc.js
+0
-1
src/templates/list_chatrooms_modal.html
src/templates/list_chatrooms_modal.html
+3
-1
No files found.
CHANGES.md
View file @
d3a45551
...
...
@@ -2,6 +2,8 @@
## 4.1.3 (Unreleased)
-
New config setting
[
locked_muc_domain
](
https://conversejs.org/docs/html/configuration.html#locked-muc-domain
)
-
#1373: Re-add support for the
[
muc_domain
](
https://conversejs.org/docs/html/configuration.html#muc-domain
)
setting
-
#1437: List of groupchats in modal doesn't scroll
## 4.1.2 (2019-02-22)
...
...
@@ -23,7 +25,7 @@
-
Bugfix: MUC invite form not appearing
-
#1369 Don't wrongly interpret message with
`subject`
as a topic change.
-
#1405 Status of contacts list are not displayed properly
-
#1408 New config option
`roomconfig_whitelist`
-
#1408 New config option
[
roomconfig_whitelist
](
https://conversejs.org/docs/html/configuration.html#roomconfig-whitelist
)
-
#1410 HTTP upload not working if conversations push proxy is used
-
#1412 MUC moderator commands can be disabled selectively by config
-
#1413 Fix moderator commands that change affiliation
...
...
dist/converse.js
View file @
d3a45551
...
...
@@ -53303,6 +53303,8 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins
_converse.api.settings.update({
'auto_list_rooms': false,
'muc_disable_moderator_commands': false,
'muc_domain': undefined,
'locked_muc_domain': undefined,
'muc_show_join_leave': true,
'roomconfig_whitelist': [],
'visible_toolbar_buttons': {
...
...
@@ -53310,6 +53312,10 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins
}
});
if (_converse.locked_muc_domain && !_.isString(_converse.muc_domain)) {
throw new Error("Config Error: it makes no sense to set locked_muc_domain " + "to true when muc_domain is not set");
}
function ___(str) {
/* This is part of a hack to get gettext to scan strings to be
* translated. Strings we cannot send to the function above because
...
...
@@ -53459,22 +53465,31 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins
initialize() {
_converse.BootstrapModal.prototype.initialize.apply(this, arguments);
if (_converse.muc_domain && !this.model.get('muc_domain')) {
this.model.save('muc_domain', _converse.muc_domain);
}
this.model.on('change:muc_domain', this.onDomainChange, this);
},
toHTML() {
const muc_domain = this.model.get('muc_domain') || _converse.muc_domain;
return templates_list_chatrooms_modal_html__WEBPACK_IMPORTED_MODULE_19___default()(_.extend(this.model.toJSON(), {
'heading_list_chatrooms': __('Query for Groupchats'),
'label_server_address': __('Server address'),
'label_query': __('Show groupchats'),
'server_placeholder': __('conference.example.org')
'show_form': !_converse.locked_muc_domain,
'server_placeholder': muc_domain ? muc_domain : __('conference.example.org')
}));
},
afterRender() {
this.el.addEventListener('shown.bs.modal', () => {
this.el.querySelector('input[name="server"]').focus();
}, false);
if (_converse.locked_muc_domain) {
this.updateRoomsList();
} else {
this.el.addEventListener('shown.bs.modal', () => this.el.querySelector('input[name="server"]').focus(), false);
}
},
openRoom(ev) {
...
...
@@ -53588,12 +53603,26 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins
'submit form.add-chatroom': 'openChatRoom'
},
initialize() {
_converse.BootstrapModal.prototype.initialize.apply(this, arguments);
this.model.on('change:muc_domain', this.render, this);
},
toHTML() {
let placeholder = '';
if (!_converse.locked_muc_domain) {
const muc_domain = this.model.get('muc_domain') || _converse.muc_domain;
placeholder = muc_domain ? `name@${muc_domain}` : __('name@conference.example.org');
}
return templates_add_chatroom_modal_html__WEBPACK_IMPORTED_MODULE_5___default()(_.extend(this.model.toJSON(), {
'heading_new_chatroom': __('Enter a new Groupchat'),
'label_room_address': __('Groupchat address'),
'label_room_address': _
converse.muc_domain ? __('Groupchat name') : _
_('Groupchat address'),
'label_nickname': __('Optional nickname'),
'chatroom_placeholder':
__('name@conference.example.org')
,
'chatroom_placeholder':
placeholder
,
'label_join': __('Join')
}));
},
...
...
@@ -53623,7 +53652,17 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins
data.nick = undefined;
}
_converse.api.rooms.open(data.jid, data);
let jid;
if (_converse.locked_muc_domain || _converse.muc_domain && !u.isValidJID(data.jid)) {
jid = `${Strophe.escapeNode(data.jid)}@${_converse.muc_domain}`;
} else {
jid = data.jid;
}
_converse.api.rooms.open(jid, _.extend(data, {
jid
}));
this.modal.hide();
ev.target.reset();
...
...
@@ -66093,7 +66132,6 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc
auto_join_on_invite: false,
auto_join_rooms: [],
auto_register_muc_nickname: false,
muc_domain: undefined,
muc_history_max_stanzas: undefined,
muc_instant_rooms: true,
muc_nickname_from_jid: false
...
...
@@ -93667,18 +93705,23 @@ return __p
var _ = {escape:__webpack_require__(/*! ./node_modules/lodash/escape.js */ "./node_modules/lodash/escape.js")};
module.exports = function(o) {
var __t, __p = '', __e = _.escape;
var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') }
__p += '<!-- src/templates/list_chatrooms_modal.html -->\n<div class="modal fade" id="list-chatrooms-modal" tabindex="-1" role="dialog" aria-labelledby="list-chatrooms-modal-label" aria-hidden="true">\n <div class="modal-dialog" role="document">\n <div class="modal-content">\n <div class="modal-header">\n <h5 class="modal-title"\n id="list-chatrooms-modal-label">' +
__e(o.heading_list_chatrooms) +
'</h5>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n <div class="modal-body d-flex flex-column">\n <form class="converse-form list-chatrooms">\n <div class="form-group">\n <label for="chatroom">' +
'</h5>\n <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n <div class="modal-body d-flex flex-column">\n ';
if (o.show_form) { ;
__p += '\n <form class="converse-form list-chatrooms">\n <div class="form-group">\n <label for="chatroom">' +
__e(o.label_server_address) +
':</label>\n <input type="text" value="' +
__e(o.muc_domain) +
'" required="required" name="server" class="form-control" placeholder="' +
__e(o.server_placeholder) +
'"/>\n </div>\n <input type="submit" class="btn btn-primary" name="
join
" value="' +
'"/>\n </div>\n <input type="submit" class="btn btn-primary" name="
list
" value="' +
__e(o.label_query) +
'"/>\n </form>\n <ul class="available-chatrooms list-group"></ul>\n </div>\n </div>\n </div>\n</div>\n';
'"/>\n </form>\n ';
} ;
__p += '\n <ul class="available-chatrooms list-group"></ul>\n </div>\n </div>\n </div>\n</div>\n';
return __p
};
docs/source/configuration.rst
View file @
d3a45551
...
...
@@ -256,7 +256,8 @@ auto_list_rooms
* Default: ``false``
If true, and the XMPP server on which the current user is logged in supports
multi-user chat, then a list of rooms on that server will be fetched.
multi-user chat, then a list of rooms on that server will be fetched in the
"Query for Groupchats" modal.
Not recommended for servers with lots of chatrooms.
...
...
@@ -264,6 +265,10 @@ For each room on the server a query is made to fetch further details (e.g.
features, number of occupants etc.), so on servers with many rooms this
option will create lots of extra connection traffic.
If the `muc_domain`_ is locked with the `locked_muc_domain`_ setting, then
rooms will automatically be fetched in the "Query for Groupchats" modal,
regardless of the value of this setting.
.. _`auto_login`:
auto_login
...
...
@@ -869,6 +874,15 @@ For example, if ``locked_domain`` is set to ``example.org``, then the user
Additionally, only users registered on the ``example.org`` host can log in, no
other users are allowed to log in.
locked_muc_domain
-----------------
* Default: ``false``
This setting allows you to restrict the multi-user chat (MUC) domain to only the value
specified in `muc_domain`_.
message_archiving
-----------------
...
...
@@ -941,11 +955,16 @@ muc_domain
* Default: ``undefined``
The MUC (multi-user chat) domain that should be used. By default Converse
will attempt to get the MUC domain from the XMPP host of the currently logged in
user.
The default MUC (multi-user chat) domain that should be used.
When setting this value, users can only enter the name when opening a new MUC,
and don't have to add the whole address (i.e. including the domain part).
Users can however still enter the domain and they can still open MUCs with
other domains.
This setting will override that.
If you want to restrict MUCs to only this domain, then set `locked_domain`_ to
``true``.
muc_history_max_stanzas
-----------------------
...
...
spec/muc.js
View file @
d3a45551
...
...
@@ -3958,13 +3958,19 @@
async
function
(
done
,
_converse
)
{
test_utils
.
openControlBox
();
_converse
.
emit
(
'
rosterContactsFetched
'
);
await
test_utils
.
waitForRoster
(
_converse
,
'
current
'
,
0
);
const
roomspanel
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
).
roomspanel
;
roomspanel
.
el
.
querySelector
(
'
.show-add-muc-modal
'
).
click
();
test_utils
.
closeControlBox
(
_converse
);
const
modal
=
roomspanel
.
add_room_modal
;
await
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
)
let
label_name
=
modal
.
el
.
querySelector
(
'
label[for="chatroom"]
'
);
expect
(
label_name
.
textContent
).
toBe
(
'
Groupchat address:
'
);
let
name_input
=
modal
.
el
.
querySelector
(
'
input[name="chatroom"]
'
);
expect
(
name_input
.
placeholder
).
toBe
(
'
name@conference.example.org
'
);
expect
(
modal
.
el
.
querySelector
(
'
.modal-title
'
).
textContent
).
toBe
(
'
Enter a new Groupchat
'
);
spyOn
(
_converse
.
ChatRoom
.
prototype
,
'
getRoomFeatures
'
).
and
.
callFake
(()
=>
Promise
.
resolve
());
roomspanel
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
...
...
@@ -3972,6 +3978,83 @@
modal
.
el
.
querySelector
(
'
form input[type="submit"]
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
length
);
await
test_utils
.
waitUntil
(()
=>
sizzle
(
'
.chatroom
'
,
_converse
.
el
).
filter
(
u
.
isVisible
).
length
===
1
);
roomspanel
.
model
.
set
(
'
muc_domain
'
,
'
muc.example.org
'
);
roomspanel
.
el
.
querySelector
(
'
.show-add-muc-modal
'
).
click
();
label_name
=
modal
.
el
.
querySelector
(
'
label[for="chatroom"]
'
);
expect
(
label_name
.
textContent
).
toBe
(
'
Groupchat address:
'
);
name_input
=
modal
.
el
.
querySelector
(
'
input[name="chatroom"]
'
);
expect
(
name_input
.
placeholder
).
toBe
(
'
name@muc.example.org
'
);
done
();
}));
it
(
"
doesn't require the domain when muc_domain is set
"
,
mock
.
initConverse
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{
'
muc_domain
'
:
'
muc.example.org
'
},
async
function
(
done
,
_converse
)
{
test_utils
.
openControlBox
();
const
roomspanel
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
).
roomspanel
;
roomspanel
.
el
.
querySelector
(
'
.show-add-muc-modal
'
).
click
();
const
modal
=
roomspanel
.
add_room_modal
;
await
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
)
expect
(
modal
.
el
.
querySelector
(
'
.modal-title
'
).
textContent
).
toBe
(
'
Enter a new Groupchat
'
);
spyOn
(
_converse
.
ChatRoom
.
prototype
,
'
getRoomFeatures
'
).
and
.
callFake
(()
=>
Promise
.
resolve
());
roomspanel
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
const
label_name
=
modal
.
el
.
querySelector
(
'
label[for="chatroom"]
'
);
expect
(
label_name
.
textContent
).
toBe
(
'
Groupchat name:
'
);
let
name_input
=
modal
.
el
.
querySelector
(
'
input[name="chatroom"]
'
);
expect
(
name_input
.
placeholder
).
toBe
(
'
name@muc.example.org
'
);
name_input
.
value
=
'
lounge
'
;
modal
.
el
.
querySelector
(
'
form input[type="submit"]
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
length
);
await
test_utils
.
waitUntil
(()
=>
sizzle
(
'
.chatroom
'
,
_converse
.
el
).
filter
(
u
.
isVisible
).
length
===
1
);
expect
(
_
.
includes
(
_converse
.
chatboxes
.
models
.
map
(
m
=>
m
.
get
(
'
id
'
)),
'
lounge@muc.example.org
'
)).
toBe
(
true
);
// However, you can still open MUCs with different domains
roomspanel
.
el
.
querySelector
(
'
.show-add-muc-modal
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
name_input
=
modal
.
el
.
querySelector
(
'
input[name="chatroom"]
'
);
name_input
.
value
=
'
lounge@conference.example.org
'
;
modal
.
el
.
querySelector
(
'
form input[type="submit"]
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
models
.
filter
(
c
=>
c
.
get
(
'
type
'
)
===
'
chatroom
'
).
length
===
2
);
await
test_utils
.
waitUntil
(()
=>
sizzle
(
'
.chatroom
'
,
_converse
.
el
).
filter
(
u
.
isVisible
).
length
===
2
);
expect
(
_
.
includes
(
_converse
.
chatboxes
.
models
.
map
(
m
=>
m
.
get
(
'
id
'
)),
'
lounge@conference.example.org
'
)).
toBe
(
true
);
done
();
}));
it
(
"
only uses the muc_domain is locked_muc_domain is true
"
,
mock
.
initConverse
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{
'
muc_domain
'
:
'
muc.example.org
'
,
'
locked_muc_domain
'
:
true
},
async
function
(
done
,
_converse
)
{
test_utils
.
openControlBox
();
const
roomspanel
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
).
roomspanel
;
roomspanel
.
el
.
querySelector
(
'
.show-add-muc-modal
'
).
click
();
const
modal
=
roomspanel
.
add_room_modal
;
await
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
)
expect
(
modal
.
el
.
querySelector
(
'
.modal-title
'
).
textContent
).
toBe
(
'
Enter a new Groupchat
'
);
spyOn
(
_converse
.
ChatRoom
.
prototype
,
'
getRoomFeatures
'
).
and
.
callFake
(()
=>
Promise
.
resolve
());
roomspanel
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
const
label_name
=
modal
.
el
.
querySelector
(
'
label[for="chatroom"]
'
);
expect
(
label_name
.
textContent
).
toBe
(
'
Groupchat name:
'
);
let
name_input
=
modal
.
el
.
querySelector
(
'
input[name="chatroom"]
'
);
expect
(
name_input
.
placeholder
).
toBe
(
''
);
name_input
.
value
=
'
lounge
'
;
modal
.
el
.
querySelector
(
'
form input[type="submit"]
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
length
);
await
test_utils
.
waitUntil
(()
=>
sizzle
(
'
.chatroom
'
,
_converse
.
el
).
filter
(
u
.
isVisible
).
length
===
1
);
expect
(
_
.
includes
(
_converse
.
chatboxes
.
models
.
map
(
m
=>
m
.
get
(
'
id
'
)),
'
lounge@muc.example.org
'
)).
toBe
(
true
);
// However, you can still open MUCs with different domains
roomspanel
.
el
.
querySelector
(
'
.show-add-muc-modal
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
name_input
=
modal
.
el
.
querySelector
(
'
input[name="chatroom"]
'
);
name_input
.
value
=
'
lounge@conference
'
;
modal
.
el
.
querySelector
(
'
form input[type="submit"]
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
models
.
filter
(
c
=>
c
.
get
(
'
type
'
)
===
'
chatroom
'
).
length
===
2
);
await
test_utils
.
waitUntil
(()
=>
sizzle
(
'
.chatroom
'
,
_converse
.
el
).
filter
(
u
.
isVisible
).
length
===
2
);
expect
(
_
.
includes
(
_converse
.
chatboxes
.
models
.
map
(
m
=>
m
.
get
(
'
id
'
)),
'
lounge
\\
40conference@muc.example.org
'
)).
toBe
(
true
);
done
();
}));
});
...
...
@@ -4002,7 +4085,9 @@
// See: http://xmpp.org/extensions/xep-0045.html#disco-rooms
expect
(
modal
.
el
.
querySelectorAll
(
'
.available-chatrooms li
'
).
length
).
toBe
(
0
);
const
input
=
modal
.
el
.
querySelector
(
'
input[name="server"]
'
).
value
=
'
chat.shakespear.lit
'
;
const
server_input
=
modal
.
el
.
querySelector
(
'
input[name="server"]
'
);
expect
(
server_input
.
placeholder
).
toBe
(
'
conference.example.org
'
);
const
input
=
server_input
.
value
=
'
chat.shakespear.lit
'
;
modal
.
el
.
querySelector
(
'
input[type="submit"]
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
length
);
expect
(
sent_stanza
.
toLocaleString
()).
toBe
(
...
...
@@ -4010,7 +4095,6 @@
`<query xmlns="http://jabber.org/protocol/disco#items"/>`
+
`</iq>`
);
const
iq
=
$iq
({
from
:
'
muc.localhost
'
,
to
:
'
dummy@localhost/pda
'
,
...
...
@@ -4029,13 +4113,19 @@
.
c
(
'
item
'
,
{
jid
:
'
street@chat.shakespeare.lit
'
,
name
:
'
A street
'
}).
nodeTree
;
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
iq
));
await
test_utils
.
waitUntil
(()
=>
modal
.
el
.
querySelectorAll
(
'
.available-chatrooms li
'
).
length
===
5
);
await
test_utils
.
waitUntil
(()
=>
modal
.
el
.
querySelectorAll
(
'
.available-chatrooms li
'
).
length
===
11
);
const
rooms
=
modal
.
el
.
querySelectorAll
(
'
.available-chatrooms li
'
);
expect
(
rooms
[
0
].
textContent
.
trim
()).
toBe
(
"
Groupchats found:
"
);
expect
(
rooms
[
1
].
textContent
.
trim
()).
toBe
(
"
A Lonely Heath
"
);
expect
(
rooms
[
2
].
textContent
.
trim
()).
toBe
(
"
A Dark Cave
"
);
expect
(
rooms
[
3
].
textContent
.
trim
()).
toBe
(
"
The Palace
"
);
expect
(
rooms
[
4
].
textContent
.
trim
()).
toBe
(
"
Macbeth's Castle
"
);
expect
(
rooms
[
5
].
textContent
.
trim
()).
toBe
(
'
Capulet
\'
s Orchard
'
);
expect
(
rooms
[
6
].
textContent
.
trim
()).
toBe
(
'
Friar Laurence
\'
s cell
'
);
expect
(
rooms
[
7
].
textContent
.
trim
()).
toBe
(
'
Hall in Capulet
\'
s house
'
);
expect
(
rooms
[
8
].
textContent
.
trim
()).
toBe
(
'
Juliet
\'
s chamber
'
);
expect
(
rooms
[
9
].
textContent
.
trim
()).
toBe
(
'
A public place
'
);
expect
(
rooms
[
10
].
textContent
.
trim
()).
toBe
(
'
A street
'
);
rooms
[
4
].
querySelector
(
'
.open-room
'
).
click
();
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
length
>
1
);
...
...
@@ -4044,6 +4134,71 @@
expect
(
view
.
el
.
querySelector
(
'
.chat-head-chatroom
'
).
textContent
.
trim
()).
toBe
(
"
Macbeth's Castle
"
);
done
();
}));
it
(
"
is pre-filled with the muc_domain
"
,
mock
.
initConverse
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{
'
muc_domain
'
:
'
muc.example.org
'
},
async
function
(
done
,
_converse
)
{
test_utils
.
openControlBox
();
const
roomspanel
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
).
roomspanel
;
roomspanel
.
el
.
querySelector
(
'
.show-list-muc-modal
'
).
click
();
test_utils
.
closeControlBox
(
_converse
);
const
modal
=
roomspanel
.
list_rooms_modal
;
await
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
const
server_input
=
modal
.
el
.
querySelector
(
'
input[name="server"]
'
);
expect
(
server_input
.
value
).
toBe
(
'
muc.example.org
'
);
done
();
}));
it
(
"
doesn't let you set the MUC domain if it's locked
"
,
mock
.
initConverse
(
null
,
[
'
rosterGroupsFetched
'
,
'
chatBoxesFetched
'
],
{
'
muc_domain
'
:
'
chat.shakespeare.lit
'
,
'
locked_muc_domain
'
:
true
},
async
function
(
done
,
_converse
)
{
test_utils
.
openControlBox
();
const
roomspanel
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
).
roomspanel
;
roomspanel
.
el
.
querySelector
(
'
.show-list-muc-modal
'
).
click
();
test_utils
.
closeControlBox
(
_converse
);
const
modal
=
roomspanel
.
list_rooms_modal
;
await
test_utils
.
waitUntil
(()
=>
u
.
isVisible
(
modal
.
el
),
1000
);
spyOn
(
_converse
.
ChatRoom
.
prototype
,
'
getRoomFeatures
'
).
and
.
callFake
(()
=>
Promise
.
resolve
());
roomspanel
.
delegateEvents
();
// We need to rebind all events otherwise our spy won't be called
expect
(
modal
.
el
.
querySelector
(
'
input[name="server"]
'
)).
toBe
(
null
);
expect
(
modal
.
el
.
querySelector
(
'
input[type="submit"]
'
)).
toBe
(
null
);
await
test_utils
.
waitUntil
(()
=>
_converse
.
chatboxes
.
length
);
const
sent_stanza
=
await
test_utils
.
waitUntil
(()
=>
_converse
.
connection
.
sent_stanzas
.
filter
(
s
=>
sizzle
(
`query[xmlns="http://jabber.org/protocol/disco#items"]`
,
s
).
length
).
pop
()
);
expect
(
Strophe
.
serialize
(
sent_stanza
)).
toBe
(
`<iq from="dummy@localhost/resource" id="
${
sent_stanza
.
getAttribute
(
'
id
'
)}
" `
+
`to="chat.shakespeare.lit" type="get" xmlns="jabber:client">`
+
`<query xmlns="http://jabber.org/protocol/disco#items"/>`
+
`</iq>`
);
const
iq
=
$iq
({
from
:
'
muc.localhost
'
,
to
:
'
dummy@localhost/pda
'
,
id
:
sent_stanza
.
getAttribute
(
'
id
'
),
type
:
'
result
'
}).
c
(
'
query
'
)
.
c
(
'
item
'
,
{
jid
:
'
heath@chat.shakespeare.lit
'
,
name
:
'
A Lonely Heath
'
}).
up
()
.
c
(
'
item
'
,
{
jid
:
'
coven@chat.shakespeare.lit
'
,
name
:
'
A Dark Cave
'
}).
up
()
.
c
(
'
item
'
,
{
jid
:
'
forres@chat.shakespeare.lit
'
,
name
:
'
The Palace
'
}).
up
()
_converse
.
connection
.
_dataRecv
(
test_utils
.
createRequest
(
iq
));
await
test_utils
.
waitUntil
(()
=>
modal
.
el
.
querySelectorAll
(
'
.available-chatrooms li
'
).
length
===
4
);
const
rooms
=
modal
.
el
.
querySelectorAll
(
'
.available-chatrooms li
'
);
expect
(
rooms
[
0
].
textContent
.
trim
()).
toBe
(
"
Groupchats found:
"
);
expect
(
rooms
[
1
].
textContent
.
trim
()).
toBe
(
"
A Lonely Heath
"
);
expect
(
rooms
[
2
].
textContent
.
trim
()).
toBe
(
"
A Dark Cave
"
);
expect
(
rooms
[
3
].
textContent
.
trim
()).
toBe
(
"
The Palace
"
);
done
();
}));
});
describe
(
"
The
\"
Groupchats
\"
section
"
,
function
()
{
...
...
@@ -4052,9 +4207,6 @@
mock
.
initConverse
(
null
,
[
'
rosterGroupsFetched
'
],
{
'
allow_bookmarks
'
:
false
},
async
function
(
done
,
_converse
)
{
// XXX: we set `allow_bookmarks` to false, so that the groupchats
// list gets rendered. Otherwise we would have to mock
// the bookmark stanza exchange.
test_utils
.
openControlBox
();
const
roomspanel
=
_converse
.
chatboxviews
.
get
(
'
controlbox
'
).
roomspanel
;
...
...
src/converse-muc-views.js
View file @
d3a45551
...
...
@@ -103,6 +103,8 @@ converse.plugins.add('converse-muc-views', {
_converse
.
api
.
settings
.
update
({
'
auto_list_rooms
'
:
false
,
'
muc_disable_moderator_commands
'
:
false
,
'
muc_domain
'
:
undefined
,
'
locked_muc_domain
'
:
undefined
,
'
muc_show_join_leave
'
:
true
,
'
roomconfig_whitelist
'
:
[],
'
visible_toolbar_buttons
'
:
{
...
...
@@ -110,6 +112,10 @@ converse.plugins.add('converse-muc-views', {
}
});
if
(
_converse
.
locked_muc_domain
&&
!
_
.
isString
(
_converse
.
muc_domain
))
{
throw
new
Error
(
"
Config Error: it makes no sense to set locked_muc_domain
"
+
"
to true when muc_domain is not set
"
);
}
function
___
(
str
)
{
/* This is part of a hack to get gettext to scan strings to be
...
...
@@ -266,22 +272,32 @@ converse.plugins.add('converse-muc-views', {
initialize
()
{
_converse
.
BootstrapModal
.
prototype
.
initialize
.
apply
(
this
,
arguments
);
if
(
_converse
.
muc_domain
&&
!
this
.
model
.
get
(
'
muc_domain
'
))
{
this
.
model
.
save
(
'
muc_domain
'
,
_converse
.
muc_domain
);
}
this
.
model
.
on
(
'
change:muc_domain
'
,
this
.
onDomainChange
,
this
);
},
toHTML
()
{
const
muc_domain
=
this
.
model
.
get
(
'
muc_domain
'
)
||
_converse
.
muc_domain
;
return
tpl_list_chatrooms_modal
(
_
.
extend
(
this
.
model
.
toJSON
(),
{
'
heading_list_chatrooms
'
:
__
(
'
Query for Groupchats
'
),
'
label_server_address
'
:
__
(
'
Server address
'
),
'
label_query
'
:
__
(
'
Show groupchats
'
),
'
server_placeholder
'
:
__
(
'
conference.example.org
'
)
'
show_form
'
:
!
_converse
.
locked_muc_domain
,
'
server_placeholder
'
:
muc_domain
?
muc_domain
:
__
(
'
conference.example.org
'
)
}));
},
afterRender
()
{
this
.
el
.
addEventListener
(
'
shown.bs.modal
'
,
()
=>
{
this
.
el
.
querySelector
(
'
input[name="server"]
'
).
focus
();
},
false
);
if
(
_converse
.
locked_muc_domain
)
{
this
.
updateRoomsList
();
}
else
{
this
.
el
.
addEventListener
(
'
shown.bs.modal
'
,
()
=>
this
.
el
.
querySelector
(
'
input[name="server"]
'
).
focus
(),
false
);
}
},
openRoom
(
ev
)
{
...
...
@@ -384,12 +400,22 @@ converse.plugins.add('converse-muc-views', {
'
submit form.add-chatroom
'
:
'
openChatRoom
'
},
initialize
()
{
_converse
.
BootstrapModal
.
prototype
.
initialize
.
apply
(
this
,
arguments
);
this
.
model
.
on
(
'
change:muc_domain
'
,
this
.
render
,
this
);
},
toHTML
()
{
let
placeholder
=
''
;
if
(
!
_converse
.
locked_muc_domain
)
{
const
muc_domain
=
this
.
model
.
get
(
'
muc_domain
'
)
||
_converse
.
muc_domain
;
placeholder
=
muc_domain
?
`name@
${
muc_domain
}
`
:
__
(
'
name@conference.example.org
'
);
}
return
tpl_add_chatroom_modal
(
_
.
extend
(
this
.
model
.
toJSON
(),
{
'
heading_new_chatroom
'
:
__
(
'
Enter a new Groupchat
'
),
'
label_room_address
'
:
__
(
'
Groupchat address
'
),
'
label_room_address
'
:
_
converse
.
muc_domain
?
__
(
'
Groupchat name
'
)
:
_
_
(
'
Groupchat address
'
),
'
label_nickname
'
:
__
(
'
Optional nickname
'
),
'
chatroom_placeholder
'
:
__
(
'
name@conference.example.org
'
)
,
'
chatroom_placeholder
'
:
placeholder
,
'
label_join
'
:
__
(
'
Join
'
),
}));
},
...
...
@@ -417,7 +443,13 @@ converse.plugins.add('converse-muc-views', {
// Make sure defaults apply if no nick is provided.
data
.
nick
=
undefined
;
}
_converse
.
api
.
rooms
.
open
(
data
.
jid
,
data
);
let
jid
;
if
(
_converse
.
locked_muc_domain
||
(
_converse
.
muc_domain
&&
!
u
.
isValidJID
(
data
.
jid
)))
{
jid
=
`
${
Strophe
.
escapeNode
(
data
.
jid
)}
@
${
_converse
.
muc_domain
}
`
;
}
else
{
jid
=
data
.
jid
}
_converse
.
api
.
rooms
.
open
(
jid
,
_
.
extend
(
data
,
{
jid
}));
this
.
modal
.
hide
();
ev
.
target
.
reset
();
}
...
...
src/headless/converse-muc.js
View file @
d3a45551
...
...
@@ -118,7 +118,6 @@ converse.plugins.add('converse-muc', {
auto_join_on_invite
:
false
,
auto_join_rooms
:
[],
auto_register_muc_nickname
:
false
,
muc_domain
:
undefined
,
muc_history_max_stanzas
:
undefined
,
muc_instant_rooms
:
true
,
muc_nickname_from_jid
:
false
...
...
src/templates/list_chatrooms_modal.html
View file @
d3a45551
...
...
@@ -9,13 +9,15 @@
</button>
</div>
<div
class=
"modal-body d-flex flex-column"
>
{[ if (o.show_form) { ]}
<form
class=
"converse-form list-chatrooms"
>
<div
class=
"form-group"
>
<label
for=
"chatroom"
>
{{{o.label_server_address}}}:
</label>
<input
type=
"text"
value=
"{{{o.muc_domain}}}"
required=
"required"
name=
"server"
class=
"form-control"
placeholder=
"{{{o.server_placeholder}}}"
/>
</div>
<input
type=
"submit"
class=
"btn btn-primary"
name=
"
join
"
value=
"{{{o.label_query}}}"
/>
<input
type=
"submit"
class=
"btn btn-primary"
name=
"
list
"
value=
"{{{o.label_query}}}"
/>
</form>
{[ } ]}
<ul
class=
"available-chatrooms list-group"
></ul>
</div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment