Refactor login form to make it more reactive.

This commit is contained in:
JC Brand 2017-09-22 10:45:03 +02:00
parent f827979000
commit 937b310733
7 changed files with 102 additions and 93 deletions

View File

@ -23,6 +23,8 @@
"tpl!login_panel", "tpl!login_panel",
"tpl!search_contact", "tpl!search_contact",
"tpl!status_option", "tpl!status_option",
"tpl!spinner",
"tpl!login_feedback",
"converse-chatview", "converse-chatview",
"converse-rosterview" "converse-rosterview"
], factory); ], factory);
@ -42,7 +44,9 @@
tpl_controlbox_toggle, tpl_controlbox_toggle,
tpl_login_panel, tpl_login_panel,
tpl_search_contact, tpl_search_contact,
tpl_status_option tpl_status_option,
tpl_spinner,
tpl_login_feedback
) { ) {
"use strict"; "use strict";
@ -266,33 +270,54 @@
}, },
insertRoster () { insertRoster () {
/* Place the rosterview inside the "Contacts" panel. /* Place the rosterview inside the "Contacts" panel. */
*/ this.contactspanel.el.insertAdjacentElement(
this.contactspanel.$el.append(_converse.rosterview.$el); 'beforeEnd',
_converse.rosterview.el
);
return this; return this;
}, },
createBrandHeadingElement () { createBrandHeadingHTML () {
return tpl_brand_heading(); return tpl_brand_heading();
}, },
insertBrandHeading () { insertBrandHeading () {
const heading_el = this.el.querySelector('.brand-heading-container');
if (_.isNull(heading_el)) {
const el = this.el.querySelector('.controlbox-head'); const el = this.el.querySelector('.controlbox-head');
el.insertAdjacentHTML('beforeend', this.createBrandHeadingElement()); el.insertAdjacentHTML('beforeend', this.createBrandHeadingHTML());
} else {
heading_el.outerHTML = this.createBrandHeadingHTML();
}
}, },
renderLoginPanel () { renderLoginPanel () {
this.loginpanel = new _converse.LoginPanel({
'$parent': this.$el.find('.controlbox-panes'),
'model': this
});
this.loginpanel.render();
this.el.classList.add("logged-out"); this.el.classList.add("logged-out");
if (_.isNil(this.loginpanel)) {
this.loginpanel = new _converse.LoginPanel({'model': this});
const panes = this.el.querySelector('.controlbox-panes');
panes.innerHTML = '';
panes.appendChild(this.loginpanel.render().el);
this.insertBrandHeading(); this.insertBrandHeading();
} else {
this.loginpanel.render();
}
return this; return this;
}, },
renderContactsPanel () { renderContactsPanel () {
/* Renders the "Contacts" panel of the controlbox.
*
* This will only be called after the user has already been
* logged in.
*/
if (this.loginpanel) {
this.loginpanel.remove();
delete this.loginpanel;
}
this.el.classList.remove("logged-out");
if (_.isUndefined(this.model.get('active-panel'))) { if (_.isUndefined(this.model.get('active-panel'))) {
this.model.save({'active-panel': USERS_PANEL_ID}); this.model.save({'active-panel': USERS_PANEL_ID});
} }
@ -305,7 +330,6 @@
'model': _converse.xmppstatus 'model': _converse.xmppstatus
}); });
_converse.xmppstatusview.render(); _converse.xmppstatusview.render();
this.el.classList.remove("logged-out");
}, },
close (ev) { close (ev) {
@ -395,19 +419,10 @@
}, },
initialize (cfg) { initialize (cfg) {
this.insertIntoDOM(cfg); _converse.connfeedback.on('change', this.renderConnectionFeedback, this);
_converse.connfeedback.on('change', this.showConnectionFeedback, this);
}, },
render () { render () {
this.$el.find('input#jid').focus();
if (!this.$el.is(':visible')) {
this.$el.show();
}
return this;
},
insertIntoDOM (cfg) {
this.el.innerHTML = tpl_login_panel({ this.el.innerHTML = tpl_login_panel({
'__': __, '__': __,
'ANONYMOUS': _converse.ANONYMOUS, 'ANONYMOUS': _converse.ANONYMOUS,
@ -416,40 +431,32 @@
'PREBIND': _converse.PREBIND, 'PREBIND': _converse.PREBIND,
'auto_login': _converse.auto_login, 'auto_login': _converse.auto_login,
'authentication': _converse.authentication, 'authentication': _converse.authentication,
'label_anon_login': __('Click here to log in anonymously'),
'placeholder_username': (_converse.locked_domain || _converse.default_domain) && __('Username') || __('user@domain'),
})
this.renderConnectionFeedback();
this.$el.find('input#jid').focus();
return this;
},
renderConnectionFeedback () {
const feedback_html = tpl_login_feedback({
'conn_feedback_class': _converse.connfeedback.get('klass'), 'conn_feedback_class': _converse.connfeedback.get('klass'),
'conn_feedback_subject': _converse.connfeedback.get('subject'), 'conn_feedback_subject': _converse.connfeedback.get('subject'),
'conn_feedback_message': _converse.connfeedback.get('message'), 'conn_feedback_message': _converse.connfeedback.get('message'),
'label_username': __('Jabber ID:'), });
'label_password': __('Password:'), const feedback_el = this.el.querySelector('.conn-feedback');
'label_anon_login': __('Click here to log in anonymously'), if (_.isNull(feedback_el)) {
'placeholder_username': (_converse.locked_domain || _converse.default_domain) && __('Username') || __('user@domain'), this.el.insertAdjacentHTML('afterbegin', feedback_html);
'placeholder_password': __('password') } else {
}) feedback_el.outerHTML = feedback_html;
cfg.$parent.html(this.el); }
}, },
showConnectionFeedback () { showSpinner () {
const klass = _converse.connfeedback.get('klass'); const form = this.el.querySelector('form');
function insert (text, el) { form.innerHTML = tpl_spinner();
el.textContent = text; return this;
if (!text) {
el.parentNode.classList.add('hidden');
} else {
el.parentNode.classList.remove('hidden');
}
el.classList.remove('error');
if (klass) {
el.classList.add(klass);
}
}
insert(
_converse.connfeedback.get('subject'),
this.el.querySelector('.conn-feedback .feedback-subject')
)
insert(
_converse.connfeedback.get('message'),
this.el.querySelector('.conn-feedback .feedback-message')
)
}, },
authenticate (ev) { authenticate (ev) {
@ -458,7 +465,7 @@
if (ev && ev.preventDefault) { ev.preventDefault(); } if (ev && ev.preventDefault) { ev.preventDefault(); }
const $form = $(ev.target); const $form = $(ev.target);
if (_converse.authentication === _converse.ANONYMOUS) { if (_converse.authentication === _converse.ANONYMOUS) {
this.connect($form, _converse.jid, null); this.showSpinner().connect(_converse.jid, null);
return; return;
} }
const $jid_input = $form.find('input[name=jid]'); const $jid_input = $form.find('input[name=jid]');
@ -490,17 +497,13 @@
} else if (_converse.default_domain && !_.includes(jid, '@')) { } else if (_converse.default_domain && !_.includes(jid, '@')) {
jid = jid + '@' + _converse.default_domain; jid = jid + '@' + _converse.default_domain;
} }
this.connect($form, jid, password); this.showSpinner().connect(jid, password);
return false; return false;
}, },
connect ($form, jid, password) { connect (jid, password) {
let resource;
if ($form) {
$form.find('input[type=submit]').hide().after('<span class="spinner login-submit"/>');
}
if (jid) { if (jid) {
resource = Strophe.getResourceFromJid(jid); const resource = Strophe.getResourceFromJid(jid);
if (!resource) { if (!resource) {
jid = jid.toLowerCase() + _converse.generateResource(); jid = jid.toLowerCase() + _converse.generateResource();
} else { } else {
@ -509,11 +512,6 @@
} }
_converse.connection.reset(); _converse.connection.reset();
_converse.connection.connect(jid, password, _converse.onConnectStatusChanged); _converse.connection.connect(jid, password, _converse.onConnectStatusChanged);
},
remove () {
this.$tabs.empty();
this.$el.parent().empty();
} }
}); });
@ -652,7 +650,6 @@
render () { render () {
this.renderTab(); this.renderTab();
let widgets = tpl_contacts_panel({ let widgets = tpl_contacts_panel({
label_online: __('Online'), label_online: __('Online'),
label_busy: __('Busy'), label_busy: __('Busy'),

View File

@ -527,7 +527,10 @@
} else if (status === Strophe.Status.AUTHENTICATING) { } else if (status === Strophe.Status.AUTHENTICATING) {
_converse.giveFeedback(__('Authenticating…')); _converse.giveFeedback(__('Authenticating…'));
} else if (status === Strophe.Status.AUTHFAIL) { } else if (status === Strophe.Status.AUTHFAIL) {
_converse.giveFeedback(__('Authentication failed: '+message), 'error'); if (!message) {
message = __('Your Jabber ID and/or password is incorrect. Please try again.');
}
_converse.giveFeedback(__('Authentication failed'), 'error', message);
_converse.setDisconnectionCause(status, message, true); _converse.setDisconnectionCause(status, message, true);
_converse.onDisconnected(); _converse.onDisconnected();
} else if (status === Strophe.Status.CONNFAIL) { } else if (status === Strophe.Status.CONNFAIL) {

View File

@ -51,15 +51,16 @@
}, },
ControlBoxView: { ControlBoxView: {
createBrandHeadingElement () { createBrandHeadingHTML() {
const div = document.createElement('div'); return tpl_brand_heading();
div.innerHTML = tpl_brand_heading();
return div.firstChild;
}, },
insertBrandHeading () { insertBrandHeading () {
const el = document.getElementById('converse-login-panel'); const el = document.getElementById('converse-login-panel');
el.parentNode.insertBefore(this.createBrandHeadingElement(), el.parentNode.firstChild); el.parentNode.insertAdjacentHTML(
'afterbegin',
this.createBrandHeadingHTML()
);
} }
}, },

View File

@ -294,7 +294,7 @@
307: __('You have been kicked from this room'), 307: __('You have been kicked from this room'),
321: __("You have been removed from this room because of an affiliation change"), 321: __("You have been removed from this room because of an affiliation change"),
322: __("You have been removed from this room because the room has changed to members-only and you're not a member"), 322: __("You have been removed from this room because the room has changed to members-only and you're not a member"),
332: __("You have been removed from this room because the MUC (Multi-user chat) service is being shut down.") 332: __("You have been removed from this room because the MUC (Multi-user chat) service is being shut down")
}, },
action_info_messages: { action_info_messages: {

View File

@ -62,14 +62,16 @@
LoginPanel: { LoginPanel: {
initialize: function (cfg) { render: function (cfg) {
const { _converse } = this.__super__; const { _converse } = this.__super__;
this.__super__.initialize.apply(this, arguments); this.__super__.render.apply(this, arguments);
if (_converse.allow_registration) { if (_converse.allow_registration) {
const div = document.createElement('div'); this.el.insertAdjacentHTML(
div.innerHTML = tpl_register_link({'__': _converse.__}) 'beforeend',
this.el.appendChild(div); tpl_register_link({'__': _converse.__})
);
} }
return this;
} }
}, },
@ -394,13 +396,18 @@
clearRegistrationForm () { clearRegistrationForm () {
const form = this.el.querySelector('form'); const form = this.el.querySelector('form');
form.innerHTML = ''; form.innerHTML = '';
this.model.set('registration_form_rendered', false);
return form; return form;
}, },
showRegistrationForm () { showRegistrationForm () {
},
showSpinner () {
const form = this.el.querySelector('form'); const form = this.el.querySelector('form');
form.classList.remove('hidden'); form.innerHTML = tpl_spinner();
return form; this.model.set('registration_form_rendered', false);
return this;
}, },
onConnectStatusChanged(status_code) { onConnectStatusChanged(status_code) {
@ -430,10 +437,8 @@
} else if (status_code === Strophe.Status.REGISTERED) { } else if (status_code === Strophe.Status.REGISTERED) {
router.navigate(); // Strip the URL fragment router.navigate(); // Strip the URL fragment
_converse.log("Registered successfully."); _converse.log("Registered successfully.");
this.model.set('registration_form_rendered', false);
_converse.connection.reset(); _converse.connection.reset();
const form = this.el.querySelector('form'); this.showSpinner();
form.innerHTML = tpl_spinner();
if (this.fields.password && this.fields.username) { if (this.fields.password && this.fields.username) {
// automatically log the user in // automatically log the user in
@ -518,8 +523,8 @@
if (!this.fields) { if (!this.fields) {
form.querySelector('.button-primary').classList.add('hidden'); form.querySelector('.button-primary').classList.add('hidden');
} }
form.classList.remove('hidden');
this.model.set('registration_form_rendered', true); this.model.set('registration_form_rendered', true);
this.showRegistrationForm();
}, },
showValidationError (message) { showValidationError (message) {

View File

@ -0,0 +1,8 @@
<div class="conn-feedback {[ if (!conn_feedback_subject && !conn_feedback_message) { ]} hidden {[ } ]}">
<p class="feedback-subject {[ if (!conn_feedback_subject) { ]} hidden {[ } ]} {{{ conn_feedback_class }}}">
{{{ conn_feedback_subject }}}
</p>
<p class="feedback-message {[ if (!conn_feedback_message) { ]} hidden {[ } ]} {{{ conn_feedback_class }}}">
{{{ conn_feedback_message }}}
</p>
</div>

View File

@ -1,8 +1,3 @@
<div class="conn-feedback hidden">
<p class="feedback-subject hidden {{{ conn_feedback_class }}}">{{{ conn_feedback_subject }}}</p>
<p class="feedback-message hidden {{{ conn_feedback_class }}}">{{{ conn_feedback_message }}}</p>
</div>
<form class="pure-form pure-form-stacked converse-form" id="converse-login" method="post"> <form class="pure-form pure-form-stacked converse-form" id="converse-login" method="post">
{[ if (auto_login) { ]} {[ if (auto_login) { ]}
<span class="spinner login-submit"/> <span class="spinner login-submit"/>
@ -11,12 +6,12 @@
<legend>{{{__("Login")}}}</legend> <legend>{{{__("Login")}}}</legend>
{[ if (authentication == LOGIN || authentication == EXTERNAL) { ]} {[ if (authentication == LOGIN || authentication == EXTERNAL) { ]}
<label>{{{label_username}}}</label> <label>{{{__("Jabber ID:")}}}</label>
<p class="form-help fade-in invalid-jid-msg error hidden">{{{_('Please enter a valid XMPP address')}}}</p> <p class="form-help fade-in invalid-jid-msg error hidden">{{{_('Please enter a valid XMPP address')}}}</p>
<input type="text" name="jid" placeholder="{{{placeholder_username}}}"> <input type="text" name="jid" placeholder="{{{placeholder_username}}}">
{[ if (authentication !== EXTERNAL) { ]} {[ if (authentication !== EXTERNAL) { ]}
<label>{{{label_password}}}</label> <label>{{{__("Password:")}}}</label>
<input type="password" name="password" placeholder="{{{placeholder_password}}}"> <input type="password" name="password" placeholder="{{{__('password')}}}">
{[ } ]} {[ } ]}
<input class="pure-button button-primary" type="submit" value="{{{__('Submit')}}}"> <input class="pure-button button-primary" type="submit" value="{{{__('Submit')}}}">
{[ } ]} {[ } ]}