New modal for adding contacts.
Remove the xhr_user_search and xhr_user_search_url options Lazily create modals
This commit is contained in:
parent
b3409fd01b
commit
e344bf769a
11
CHANGES.md
11
CHANGES.md
|
@ -2,10 +2,21 @@
|
|||
|
||||
## 4.0.0 (Unreleased)
|
||||
|
||||
## Removed configuration settings
|
||||
|
||||
Due to rewriting parts of the code, we regrettably had to remove certain
|
||||
lesser-used configuration settings because the cost of adding them to the
|
||||
new code was too high.
|
||||
|
||||
If you relied on any of these settings, you can reproduce their
|
||||
functionality in your own 3rd party plugins, or you can [contact us](http://opkode.com/contact.html)
|
||||
with regards to sponsoring development on reintroducing them.
|
||||
|
||||
* Removed the `xhr_custom_status` and `xhr_custom_status_url` configuration
|
||||
settings. If you relied on these settings, you can instead listen for the
|
||||
[statusMessageChanged](https://conversejs.org/docs/html/events.html#contactstatusmessagechanged)
|
||||
event and make the XMLHttpRequest yourself.
|
||||
* Removed the `xhr_user_search` and `xhr_user_search_url` configuration options.
|
||||
|
||||
|
||||
## 3.3.4 (Unreleased)
|
||||
|
|
|
@ -1524,48 +1524,3 @@ An example from `the embedded room demo <https://conversejs.org/demo/embedded.ht
|
|||
whitelisted_plugins: ['converse-muc-embedded']
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
xhr_user_search
|
||||
---------------
|
||||
|
||||
* Default: ``false``
|
||||
|
||||
.. note::
|
||||
XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous JavaScript and XML).
|
||||
|
||||
There are two ways to add users.
|
||||
|
||||
* The user inputs a valid JID (Jabber ID), and the user is added as a pending contact.
|
||||
* The user inputs some text (for example part of a first name or last name),
|
||||
an XHR (Ajax Request) will be made to a remote server, and a list of matches are returned.
|
||||
The user can then choose one of the matches to add as a contact.
|
||||
|
||||
This setting enables the second mechanism, otherwise by default the first will be used.
|
||||
|
||||
*What is expected from the remote server?*
|
||||
|
||||
A default JSON encoded list of objects must be returned. Each object
|
||||
corresponds to a matched user and needs the keys ``id`` and ``fullname``.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
[{"id": "foo", "fullname": "Foo McFoo"}, {"id": "bar", "fullname": "Bar McBar"}]
|
||||
|
||||
.. note::
|
||||
Make sure your server script sets the header `Content-Type: application/json`.
|
||||
|
||||
xhr_user_search_url
|
||||
-------------------
|
||||
|
||||
.. note::
|
||||
XHR stands for XMLHTTPRequest, and is meant here in the AJAX sense (Asynchronous JavaScript and XML).
|
||||
|
||||
* Default: Empty string
|
||||
|
||||
Used only in conjunction with ``xhr_user_search``.
|
||||
|
||||
This is the URL to which an XHR GET request will be made to fetch user data from your remote server.
|
||||
The query string will be included in the request with ``q`` as its key.
|
||||
|
||||
The data returned must be a JSON encoded list of user JIDs.
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="pure-form add-xmpp-contact">
|
||||
<form class="converse-form add-xmpp-contact">
|
||||
<div class="form-group">
|
||||
<input type="text" name="identifier" class="form-control" placeholder="Contact username">
|
||||
</div>
|
||||
|
|
|
@ -9,13 +9,10 @@
|
|||
(function (root, factory) {
|
||||
define(["converse-core",
|
||||
"lodash.fp",
|
||||
"tpl!add_contact_dropdown",
|
||||
"tpl!add_contact_form",
|
||||
"tpl!converse_brand_heading",
|
||||
"tpl!controlbox",
|
||||
"tpl!controlbox_toggle",
|
||||
"tpl!login_panel",
|
||||
"tpl!search_contact",
|
||||
"converse-chatview",
|
||||
"converse-rosterview",
|
||||
"converse-profile"
|
||||
|
@ -23,13 +20,10 @@
|
|||
}(this, function (
|
||||
converse,
|
||||
fp,
|
||||
tpl_add_contact_dropdown,
|
||||
tpl_add_contact_form,
|
||||
tpl_brand_heading,
|
||||
tpl_controlbox,
|
||||
tpl_controlbox_toggle,
|
||||
tpl_login_panel,
|
||||
tpl_search_contact
|
||||
tpl_login_panel
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
|
@ -86,7 +80,7 @@
|
|||
*
|
||||
* NB: These plugins need to have already been loaded via require.js.
|
||||
*/
|
||||
dependencies: ["converse-chatboxes", "converse-rosterview", "converse-chatview"],
|
||||
dependencies: ["converse-modal", "converse-chatboxes", "converse-rosterview", "converse-chatview"],
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
|
@ -212,9 +206,7 @@
|
|||
default_domain: undefined,
|
||||
locked_domain: undefined,
|
||||
show_controlbox_by_default: false,
|
||||
sticky_controlbox: false,
|
||||
xhr_user_search: false,
|
||||
xhr_user_search_url: ''
|
||||
sticky_controlbox: false
|
||||
});
|
||||
|
||||
_converse.api.promises.add('controlboxInitialized');
|
||||
|
@ -230,13 +222,6 @@
|
|||
})
|
||||
|
||||
|
||||
_converse.AddContactModal = Backbone.VDOMView.extend({
|
||||
events: {
|
||||
'submit form': 'addContact'
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
_converse.ControlBoxView = _converse.ChatBoxView.extend({
|
||||
tagName: 'div',
|
||||
className: 'chatbox',
|
||||
|
@ -528,12 +513,6 @@
|
|||
_converse.ControlBoxPane = Backbone.NativeView.extend({
|
||||
tagName: 'div',
|
||||
className: 'controlbox-pane',
|
||||
events: {
|
||||
'click a.toggle-xmpp-contact-form': 'toggleContactForm',
|
||||
'submit form.add-xmpp-contact': 'addContactFromForm',
|
||||
'submit form.search-xmpp-contact': 'searchContacts',
|
||||
'click a.subscribe-to-user': 'addContactFromList'
|
||||
},
|
||||
|
||||
initialize () {
|
||||
_converse.xmppstatusview = new _converse.XMPPStatusView({
|
||||
|
@ -543,103 +522,6 @@
|
|||
'afterBegin',
|
||||
_converse.xmppstatusview.render().el
|
||||
);
|
||||
},
|
||||
|
||||
generateAddContactHTML (settings={}) {
|
||||
if (_converse.xhr_user_search) {
|
||||
return tpl_search_contact({
|
||||
label_contact_name: __('Contact name'),
|
||||
label_search: __('Search')
|
||||
});
|
||||
} else {
|
||||
return tpl_add_contact_form(_.assign({
|
||||
error_message: null,
|
||||
label_contact_username: __('e.g. user@example.org'),
|
||||
label_add: __('Add'),
|
||||
value: ''
|
||||
}, settings));
|
||||
}
|
||||
},
|
||||
|
||||
toggleContactForm (ev) {
|
||||
ev.preventDefault();
|
||||
this.el.querySelector('.search-xmpp div').innerHTML = this.generateAddContactHTML();
|
||||
var dropdown = this.el.querySelector('.contact-form-container');
|
||||
u.slideToggleElement(dropdown).then(() => {
|
||||
if (u.isVisible(dropdown)) {
|
||||
dropdown.querySelector('input.username').focus();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
searchContacts (ev) {
|
||||
ev.preventDefault();
|
||||
const search_query= ev.target.querySelector('input.username').value,
|
||||
url = _converse.xhr_user_search_url+ "?q=" + search_query,
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open('GET', url, true);
|
||||
xhr.setRequestHeader('Accept', "application/json, text/javascript");
|
||||
|
||||
xhr.onload = function () {
|
||||
if (xhr.status >= 200 && xhr.status < 400) {
|
||||
const data = JSON.parse(xhr.responseText),
|
||||
ul = _converse.root.querySelector('.search-xmpp ul');
|
||||
u.removeElement(ul.querySelector('li.found-user'));
|
||||
u.removeElement(ul.querySelector('li.chat-info'));
|
||||
if (!data.length) {
|
||||
const no_users_text = __('No users found');
|
||||
ul.insertAdjacentHTML('beforeEnd', `<li class="chat-info">${no_users_text}</li>`);
|
||||
}
|
||||
else {
|
||||
const title_subscribe = __('Click to add as a chat contact');
|
||||
_.each(data, function (obj) {
|
||||
const li = u.stringToElement('<li class="found-user"></li>'),
|
||||
a = u.stringToElement(`<a class="subscribe-to-user" href="#" title="${title_subscribe}"></a>`),
|
||||
jid = Strophe.getNodeFromJid(obj.id)+"@"+Strophe.getDomainFromJid(obj.id);
|
||||
|
||||
a.setAttribute('data-recipient', jid);
|
||||
a.textContent = obj.fullname;
|
||||
li.appendChild(a);
|
||||
u.appendChild(li)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
xhr.onerror();
|
||||
}
|
||||
};
|
||||
xhr.onerror = function () {
|
||||
_converse.log('Could not fetch contacts via XHR', Strophe.LogLevel.ERROR);
|
||||
};
|
||||
xhr.send();
|
||||
},
|
||||
|
||||
addContactFromForm (ev) {
|
||||
ev.preventDefault();
|
||||
const input = ev.target.querySelector('input');
|
||||
const jid = input.value;
|
||||
if (!jid || _.compact(jid.split('@')).length < 2) {
|
||||
this.el.querySelector('.search-xmpp div').innerHTML =
|
||||
this.generateAddContactHTML({
|
||||
error_message: __('Please enter a valid XMPP address'),
|
||||
label_contact_username: __('e.g. user@example.org'),
|
||||
label_add: __('Add'),
|
||||
value: jid
|
||||
});
|
||||
return;
|
||||
}
|
||||
_converse.roster.addAndSubscribe(jid);
|
||||
u.slideIn(this.el.querySelector('.contact-form-container'));
|
||||
},
|
||||
|
||||
addContactFromList (ev) {
|
||||
ev.preventDefault();
|
||||
const jid = ev.target.getAttribute('data-recipient'),
|
||||
name = ev.target.textContent;
|
||||
_converse.roster.addAndSubscribe(jid, name);
|
||||
const parent = ev.target.parentNode;
|
||||
parent.parentNode.removeChild(parent);
|
||||
u.slideIn(this.el.querySelector('.contact-form-container'));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
},
|
||||
|
||||
show (ev) {
|
||||
ev.preventDefault();
|
||||
this.trigger_el = ev.target;
|
||||
this.trigger_el.classList.add('selected');
|
||||
this.render();
|
||||
this.modal.show();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2184,11 +2184,6 @@
|
|||
'click a.room-info': 'toggleRoomInfo'
|
||||
},
|
||||
|
||||
initialize (cfg) {
|
||||
this.add_room_modal = new _converse.AddChatRoomModal({'model': this.model});
|
||||
this.list_rooms_modal = new _converse.ListChatRoomsModal({'model': this.model});
|
||||
},
|
||||
|
||||
render () {
|
||||
this.el.innerHTML = tpl_room_panel({
|
||||
'heading_chatrooms': __('Chatrooms'),
|
||||
|
@ -2204,12 +2199,16 @@
|
|||
},
|
||||
|
||||
showAddRoomModal (ev) {
|
||||
ev.preventDefault();
|
||||
if (_.isUndefined(this.add_room_modal)) {
|
||||
this.add_room_modal = new _converse.AddChatRoomModal({'model': this.model});
|
||||
}
|
||||
this.add_room_modal.show(ev);
|
||||
},
|
||||
|
||||
showListRoomsModal(ev) {
|
||||
ev.preventDefault();
|
||||
if (_.isUndefined(this.list_rooms_modal)) {
|
||||
this.list_rooms_modal = new _converse.ListChatRoomsModal({'model': this.model});
|
||||
}
|
||||
this.list_rooms_modal.show(ev);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"tpl!chat_status_modal",
|
||||
"tpl!profile_view",
|
||||
"tpl!status_option",
|
||||
"converse-vcard"
|
||||
"converse-vcard",
|
||||
"converse-modal"
|
||||
], factory);
|
||||
}(this, function (
|
||||
converse,
|
||||
|
@ -29,6 +30,8 @@
|
|||
|
||||
converse.plugins.add('converse-profile', {
|
||||
|
||||
dependencies: ["converse-modal"],
|
||||
|
||||
initialize () {
|
||||
/* The initialize function gets called as soon as the plugin is
|
||||
* loaded by converse.js's plugin machinery.
|
||||
|
@ -37,20 +40,12 @@
|
|||
{ __ } = _converse;
|
||||
|
||||
|
||||
_converse.ChatStatusModal = Backbone.VDOMView.extend({
|
||||
_converse.ChatStatusModal = _converse.BootstrapModal.extend({
|
||||
events: {
|
||||
"submit form#set-xmpp-status": "onFormSubmitted",
|
||||
"click .clear-input": "clearStatusMessage"
|
||||
},
|
||||
|
||||
initialize () {
|
||||
this.render().insertIntoDOM();
|
||||
this.modal = new bootstrap.Modal(this.el, {
|
||||
backdrop: 'static',
|
||||
keyboard: true
|
||||
});
|
||||
},
|
||||
|
||||
toHTML () {
|
||||
return tpl_chat_status_modal(_.extend(this.model.toJSON(), {
|
||||
'label_away': __('Away'),
|
||||
|
@ -67,16 +62,6 @@
|
|||
}));
|
||||
},
|
||||
|
||||
insertIntoDOM () {
|
||||
const container_el = _converse.chatboxviews.el.querySelector('#converse-modals');
|
||||
container_el.insertAdjacentElement('beforeEnd', this.el);
|
||||
},
|
||||
|
||||
show () {
|
||||
this.render();
|
||||
this.modal.show();
|
||||
},
|
||||
|
||||
clearStatusMessage (ev) {
|
||||
if (ev && ev.preventDefault) {
|
||||
ev.preventDefault();
|
||||
|
@ -107,7 +92,6 @@
|
|||
|
||||
initialize () {
|
||||
this.model.on("change", this.render, this);
|
||||
this.status_modal = new _converse.ChatStatusModal({model: this.model});
|
||||
},
|
||||
|
||||
toHTML () {
|
||||
|
@ -125,8 +109,10 @@
|
|||
},
|
||||
|
||||
showStatusChangeModal (ev) {
|
||||
ev.preventDefault();
|
||||
this.status_modal.show();
|
||||
if (_.isUndefined(this.status_modal)) {
|
||||
this.status_modal = new _converse.ChatStatusModal({model: this.model});
|
||||
}
|
||||
this.status_modal.show(ev);
|
||||
},
|
||||
|
||||
logOut (ev) {
|
||||
|
|
|
@ -8,22 +8,28 @@
|
|||
|
||||
(function (root, factory) {
|
||||
define(["converse-core",
|
||||
"tpl!add_contact_modal",
|
||||
"tpl!group_header",
|
||||
"tpl!pending_contact",
|
||||
"tpl!requesting_contact",
|
||||
"tpl!roster",
|
||||
"tpl!roster_filter",
|
||||
"tpl!roster_item",
|
||||
"converse-chatboxes"
|
||||
"tpl!search_contact",
|
||||
"converse-chatboxes",
|
||||
"converse-modal"
|
||||
], factory);
|
||||
}(this, function (
|
||||
converse,
|
||||
tpl_add_contact_modal,
|
||||
tpl_group_header,
|
||||
tpl_pending_contact,
|
||||
tpl_requesting_contact,
|
||||
tpl_roster,
|
||||
tpl_roster_filter,
|
||||
tpl_roster_item) {
|
||||
tpl_roster_item,
|
||||
tpl_search_contact
|
||||
) {
|
||||
"use strict";
|
||||
const { Backbone, Strophe, $iq, b64_sha1, sizzle, _ } = converse.env;
|
||||
const u = converse.env.utils;
|
||||
|
@ -31,6 +37,8 @@
|
|||
|
||||
converse.plugins.add('converse-rosterview', {
|
||||
|
||||
dependencies: ["converse-modal"],
|
||||
|
||||
overrides: {
|
||||
// Overrides mentioned here will be picked up by converse.js's
|
||||
// plugin architecture they will replace existing methods on the
|
||||
|
@ -118,6 +126,47 @@
|
|||
};
|
||||
|
||||
|
||||
_converse.AddContactModal = _converse.BootstrapModal.extend({
|
||||
events: {
|
||||
'click a.subscribe-to-user': 'addContactFromList',
|
||||
'submit form': 'addContactFromForm',
|
||||
'submit form.search-xmpp-contact': 'searchContacts'
|
||||
},
|
||||
|
||||
initialize () {
|
||||
_converse.BootstrapModal.prototype.initialize.apply(this, arguments);
|
||||
this.model.on('change', this.render, this);
|
||||
},
|
||||
|
||||
toHTML () {
|
||||
return tpl_add_contact_modal(_.extend(this.model.toJSON(), {
|
||||
'heading_new_contact': __('Add a Contact'),
|
||||
'label_xmpp_address': __('XMPP Address'),
|
||||
'label_nickname': __('Optional nickname'),
|
||||
'contact_placeholder': __('name@example.org'),
|
||||
'label_add': __('Add'),
|
||||
}));
|
||||
},
|
||||
|
||||
addContactFromForm (ev) {
|
||||
ev.preventDefault();
|
||||
const data = new FormData(ev.target),
|
||||
jid = data.get('jid');
|
||||
|
||||
if (!jid || _.compact(jid.split('@')).length < 2) {
|
||||
this.model.set({
|
||||
'error_message': __('Please enter a valid XMPP address'),
|
||||
'jid': jid
|
||||
})
|
||||
} else {
|
||||
_converse.roster.addAndSubscribe(jid);
|
||||
this.model.clear();
|
||||
this.modal.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
_converse.RosterFilter = Backbone.Model.extend({
|
||||
initialize () {
|
||||
this.set({
|
||||
|
@ -620,6 +669,11 @@
|
|||
sortEvent: null, // Groups are immutable, so they don't get re-sorted
|
||||
subviewIndex: 'name',
|
||||
|
||||
events: {
|
||||
'click a.chatbox-btn.add-contact': 'showAddContactModal',
|
||||
|
||||
},
|
||||
|
||||
initialize () {
|
||||
Backbone.OrderedListView.prototype.initialize.apply(this, arguments);
|
||||
|
||||
|
@ -666,6 +720,13 @@
|
|||
return this;
|
||||
},
|
||||
|
||||
showAddContactModal (ev) {
|
||||
if (_.isUndefined(this.add_contact_modal)) {
|
||||
this.add_contact_modal = new _converse.AddContactModal({'model': new Backbone.Model()});
|
||||
}
|
||||
this.add_contact_modal.show(ev);
|
||||
},
|
||||
|
||||
createRosterFilter () {
|
||||
// Create a model on which we can store filter properties
|
||||
const model = new _converse.RosterFilter();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div class="modal fade" id="chatroomsModal" tabindex="-1" role="dialog" aria-labelledby="chatroomsModalLabel" aria-hidden="true">
|
||||
<div class="modal fade" id="add-chatroom-modal" tabindex="-1" role="dialog" aria-labelledby="add-chatroom-modal-label" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"
|
||||
id="chatroomsModalLabel">{{{o.heading_new_chatroom}}}</h5>
|
||||
id="add-chatroom-modal-label">{{{o.heading_new_chatroom}}}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
@ -11,11 +11,11 @@
|
|||
<div class="modal-body">
|
||||
<form class="converse-form add-chatroom">
|
||||
<div class="form-group">
|
||||
<label for="server">{{{o.label_room_address}}}:</label>
|
||||
<input type="text" value="{{{o.muc_domain}}}" required="required" name="chatroom" class="form-control" placeholder="{{{o.chatroom_placeholder}}}">
|
||||
<label for="chatroom">{{{o.label_room_address}}}:</label>
|
||||
<input type="text" required="required" name="chatroom" class="form-control" placeholder="{{{o.chatroom_placeholder}}}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="chatroom">{{{o.label_nickname}}}:</label>
|
||||
<label for="nickname">{{{o.label_nickname}}}:</label>
|
||||
<input type="text" name="nickname" value="{{{o.nick}}}" class="form-control">
|
||||
</div>
|
||||
<input type="submit" class="btn btn-primary" name="join" value="{{{o.label_join}}}">
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<dl class="add-converse-contact dropdown">
|
||||
<dt id="xmpp-contact-search" class="fancy-dropdown">
|
||||
<a class="toggle-xmpp-contact-form icon-plus" href="#" title="{{{o.label_click_to_chat}}}"> {{{o.label_add_contact}}}</a>
|
||||
</dt>
|
||||
<dd class="search-xmpp">
|
||||
<div class="contact-form-container collapsed"></div>
|
||||
<ul></ul>
|
||||
</dd>
|
||||
</dl>
|
27
src/templates/add_contact_modal.html
Normal file
27
src/templates/add_contact_modal.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!-- Add contact Modal -->
|
||||
<div class="modal fade" id="add-contact-modal" tabindex="-1" role="dialog" aria-labelledby="addContactModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addContactModalLabel">{{{o.heading_new_contact}}}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<form class="converse-form add-xmpp-contact">
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="jid">{{{o.label_xmpp_address}}}:</label>
|
||||
<input type="text" name="jid" required="required" value="{{{o.jid}}}"
|
||||
class="form-control {[ if (o.error_message) { ]} is-invalid {[ } ]}"
|
||||
placeholder="{{{o.contact_placeholder}}}">
|
||||
{[ if (o.error_message) { ]}
|
||||
<div class="invalid-feedback">{{{o.error_message}}}</div>
|
||||
{[ } ]}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary">{{{o.label_add}}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,15 +1,15 @@
|
|||
<div class="modal fade" id="list-chatrooms-modal" tabindex="-1" role="dialog" aria-labelledby="chatroomsModalLabel" aria-hidden="true">
|
||||
<div class="modal fade" id="list-chatrooms-modal" tabindex="-1" role="dialog" aria-labelledby="list-chatrooms-modal-label" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"
|
||||
id="chatroomsModalLabel">{{{o.heading_list_chatrooms}}}</h5>
|
||||
id="list-chatrooms-modal-label">{{{o.heading_list_chatrooms}}}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="converse-form add-chatroom">
|
||||
<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}}}">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="d-flex">
|
||||
<span class="w-100">{{{o.heading_chatrooms}}}</span>
|
||||
<a class="chatbox-btn fa fa-list-ul" title="{{{o.title_list_rooms}}}" data-toggle="modal" data-target="#list-chatrooms-modal"></a>
|
||||
<a class="chatbox-btn fa fa-users" title="{{{o.title_new_room}}}" data-toggle="modal" data-target="#chatroomsModal"></a>
|
||||
<a class="chatbox-btn fa fa-users" title="{{{o.title_new_room}}}" data-toggle="modal" data-target="#add-chatrooms-modal"></a>
|
||||
</div>
|
||||
<div class="list-container open-rooms-list rooms-list-container"></div>
|
||||
<div class="list-container bookmarks-list rooms-list-container"></div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="d-flex">
|
||||
<span class="w-100">{{{o.heading_contacts}}}</span>
|
||||
<a class="chatbox-btn fa fa-user-plus" title="{{{o.title_add_contact}}}"
|
||||
data-toggle="modal" data-target="#addContactModal"></a>
|
||||
<a class="chatbox-btn add-contact fa fa-user-plus" title="{{{o.title_add_contact}}}"
|
||||
data-toggle="modal" data-target="#add-contact-modal"></a>
|
||||
</div>
|
||||
|
||||
<form class="roster-filter-form"></form>
|
||||
|
|
Loading…
Reference in New Issue
Block a user