Commit 9372ad2d authored by JC Brand's avatar JC Brand

register: Use lit-html to render templates

parent e31fa1f7
...@@ -109,6 +109,11 @@ body.converse-fullscreen { ...@@ -109,6 +109,11 @@ body.converse-fullscreen {
padding: 0 !important; padding: 0 !important;
} }
.no-scrolling {
overflow-x: none;
overflow-y: none;
}
&.converse-overlayed { &.converse-overlayed {
> .row { > .row {
flex-direction: row-reverse; flex-direction: row-reverse;
......
...@@ -5,7 +5,7 @@ const $iq = converse.env.$iq; ...@@ -5,7 +5,7 @@ const $iq = converse.env.$iq;
const { _, sizzle} = converse.env; const { _, sizzle} = converse.env;
const u = converse.env.utils; const u = converse.env.utils;
describe("The Registration Panel", function () { fdescribe("The Registration Panel", function () {
it("is not available unless allow_registration=true", it("is not available unless allow_registration=true",
mock.initConverse( mock.initConverse(
......
...@@ -2,9 +2,7 @@ import log from "@converse/headless/log"; ...@@ -2,9 +2,7 @@ import log from "@converse/headless/log";
import tpl_form_input from "templates/form_input.js"; import tpl_form_input from "templates/form_input.js";
import tpl_form_url from "templates/form_url.js"; import tpl_form_url from "templates/form_url.js";
import tpl_form_username from "templates/form_username.js"; import tpl_form_username from "templates/form_username.js";
import tpl_register_panel from "./templates/register_panel.html"; import tpl_register_panel from "./templates/register_panel.js";
import tpl_registration_form from "./templates/registration_form.js";
import tpl_registration_request from "./templates/registration_request.html";
import tpl_spinner from "templates/spinner.js"; import tpl_spinner from "templates/spinner.js";
import utils from "@converse/headless/utils/form"; import utils from "@converse/headless/utils/form";
import { View } from "@converse/skeletor/src/view"; import { View } from "@converse/skeletor/src/view";
...@@ -18,6 +16,11 @@ const { Strophe, sizzle, $iq } = converse.env; ...@@ -18,6 +16,11 @@ const { Strophe, sizzle, $iq } = converse.env;
const u = converse.env.utils; const u = converse.env.utils;
const CHOOSE_PROVIDER = 0;
const FETCHING_FORM = 1;
const REGISTRATION_FORM = 2;
/** /**
* @class * @class
* @namespace _converse.RegisterPanel * @namespace _converse.RegisterPanel
...@@ -35,29 +38,33 @@ const RegisterPanel = View.extend({ ...@@ -35,29 +38,33 @@ const RegisterPanel = View.extend({
initialize () { initialize () {
this.reset(); this.reset();
api.listen.on('connectionInitialized', () => this.registerHooks()); api.listen.on('connectionInitialized', () => this.registerHooks());
this.listenTo(this.model, 'change:registration_status', this.render);
const domain = api.settings.get('registration_domain');
if (domain) {
this.fetchRegistrationForm(domain);
} else {
this.model.set('registration_status', CHOOSE_PROVIDER);
}
}, },
render () { render () {
this.model.set('registration_form_rendered', false); render(tpl_register_panel({
this.el.innerHTML = tpl_register_panel({ 'domain': this.domain,
'__': __, 'fields': this.fields,
'default_domain': api.settings.get('registration_domain'), 'form_fields': this.form_fields,
'label_register': __('Fetch registration form'), 'instructions': this.instructions,
'help_providers': __('Tip: A list of public XMPP providers is available'), 'model': this.model,
'help_providers_link': __('here'), 'title': this.title,
'href_providers': api.settings.get('providers_link'), }), this.el);
'domain_placeholder': api.settings.get('domain_placeholder')
});
if (api.settings.get('registration_domain')) {
this.fetchRegistrationForm(api.settings.get('registration_domain'));
}
return this; return this;
}, },
/**
* Hook into Strophe's _connect_cb, so that we can send an IQ
* requesting the registration fields.
*/
registerHooks () { registerHooks () {
/* Hook into Strophe's _connect_cb, so that we can send an IQ
* requesting the registration fields.
*/
const conn = _converse.connection; const conn = _converse.connection;
const connect_cb = conn._connect_cb.bind(conn); const connect_cb = conn._connect_cb.bind(conn);
conn._connect_cb = (req, callback, raw) => { conn._connect_cb = (req, callback, raw) => {
...@@ -136,7 +143,7 @@ const RegisterPanel = View.extend({ ...@@ -136,7 +143,7 @@ const RegisterPanel = View.extend({
return false; return false;
} }
this.setFields(stanza); this.setFields(stanza);
if (!this.model.get('registration_form_rendered')) { if (this.model.get('registration_status') === FETCHING_FORM) {
this.renderRegistrationForm(stanza); this.renderRegistrationForm(stanza);
} }
return false; return false;
...@@ -200,9 +207,7 @@ const RegisterPanel = View.extend({ ...@@ -200,9 +207,7 @@ const RegisterPanel = View.extend({
* @param { String } domain_name - XMPP server domain * @param { String } domain_name - XMPP server domain
*/ */
async fetchRegistrationForm (domain_name) { async fetchRegistrationForm (domain_name) {
if (!this.model.get('registration_form_rendered')) { this.model.set('registration_status', FETCHING_FORM);
this.renderRegistrationRequest();
}
this.reset({ this.reset({
'domain': Strophe.getDomainFromJid(domain_name), 'domain': Strophe.getDomainFromJid(domain_name),
'_registering': true '_registering': true
...@@ -214,21 +219,6 @@ const RegisterPanel = View.extend({ ...@@ -214,21 +219,6 @@ const RegisterPanel = View.extend({
return false; return false;
}, },
/**
* Clear the form and inform the user that the registration
* form is being fetched.
* @private
*/
renderRegistrationRequest () {
this.clearRegistrationForm().insertAdjacentHTML(
'beforeend',
tpl_registration_request({
'__': _converse.__,
'cancel': api.settings.get('registration_domain'),
})
);
},
giveFeedback (message, klass) { giveFeedback (message, klass) {
let feedback = this.el.querySelector('.reg-feedback'); let feedback = this.el.querySelector('.reg-feedback');
if (feedback !== null) { if (feedback !== null) {
...@@ -243,17 +233,9 @@ const RegisterPanel = View.extend({ ...@@ -243,17 +233,9 @@ const RegisterPanel = View.extend({
} }
}, },
clearRegistrationForm () {
const form = this.el.querySelector('form');
form.innerHTML = '';
this.model.set('registration_form_rendered', false);
return form;
},
showSpinner () { showSpinner () {
const form = this.el.querySelector('form'); const form = this.el.querySelector('form');
render(tpl_spinner(), form); render(tpl_spinner(), form);
this.model.set('registration_form_rendered', false);
return this; return this;
}, },
...@@ -346,17 +328,8 @@ const RegisterPanel = View.extend({ ...@@ -346,17 +328,8 @@ const RegisterPanel = View.extend({
* @param { XMLElement } stanza - The IQ stanza received from the XMPP server. * @param { XMLElement } stanza - The IQ stanza received from the XMPP server.
*/ */
renderRegistrationForm (stanza) { renderRegistrationForm (stanza) {
const form = this.el.querySelector('form'); this.form_fields = this.getFormFields(stanza);
const tpl = tpl_registration_form({ this.model.set('registration_status', REGISTRATION_FORM);
'domain': this.domain,
'title': this.title,
'instructions': this.instructions,
'fields': this.fields,
'form_fields': this.getFormFields(stanza)
});
render(tpl, form);
form.classList.remove('hidden');
this.model.set('registration_form_rendered', true);
}, },
showValidationError (message) { showValidationError (message) {
...@@ -408,11 +381,9 @@ const RegisterPanel = View.extend({ ...@@ -408,11 +381,9 @@ const RegisterPanel = View.extend({
abortRegistration () { abortRegistration () {
_converse.connection._proto._abortAllRequests(); _converse.connection._proto._abortAllRequests();
_converse.connection.reset(); _converse.connection.reset();
if (this.model.get('registration_form_rendered')) { if ([FETCHING_FORM, REGISTRATION_FORM].includes(this.model.get('registration_status'))) {
if (api.settings.get('registration_domain') && this.model.get('registration_form_rendered')) { if (api.settings.get('registration_domain')) {
this.fetchRegistrationForm( this.fetchRegistrationForm(api.settings.get('registration_domain'));
api.settings.get('registration_domain')
);
} }
} else { } else {
this.render(); this.render();
......
<div>
<form id="converse-register" class="converse-form">
<legend class="col-form-label">{{{o.__("Create your account")}}}</legend>
<div class="form-group">
<label>{{{o.__("Please enter the XMPP provider to register with:")}}}</label>
<div class="form-errors hidden"></div>
{[ if (o.default_domain) { ]}
{{{o.default_domain}}}
</div>
{[ } else { ]}
<input class="form-control" required="required" type="text" name="domain" placeholder="{{{o.domain_placeholder}}}"/>
<p class="form-text text-muted">{{{o.help_providers}}} <a href="{{{o.href_providers}}}" class="url" target="_blank" rel="noopener">{{{o.help_providers_link}}}</a>.</p>
</div>
<fieldset class="buttons">
<input class="btn btn-primary" type="submit" value="{{{o.label_register}}}"/>
<div class="switch-form">
<p>{{{ o.__("Already have a chat account?") }}}</p>
<p><a class="login-here toggle-register-login" href="#converse/login">{{{o.__("Log in here")}}}</a></p>
</div>
</fieldset>
{[ } ]}
<!--</div>-->
</form>
</div>
import tpl_registration_form from './registration_form.js';
import tpl_spinner from 'templates/spinner.js';
import { __ } from 'i18n';
import { api } from '@converse/headless/core';
import { html } from 'lit-html';
const tpl_form_request = () => {
const default_domain = api.settings.get('registration_domain');
const i18n_fetch_form = __("Hold tight, we're fetching the registration form…");
const i18n_cancel = __('Cancel');
return html`
<form id="converse-register" class="converse-form no-scrolling">
${tpl_spinner({ 'classes': 'hor_centered' })}
<p class="info">${i18n_fetch_form}</p>
${default_domain
? ''
: html`
<button class="btn btn-secondary button-cancel hor_centered">${i18n_cancel}</button>
`}
</form>
`;
};
const tpl_domain_input = () => {
const domain_placeholder = api.settings.get('domain_placeholder');
const i18n_providers = __('Tip: A list of public XMPP providers is available');
const i18n_providers_link = __('here');
const href_providers = api.settings.get('providers_link');
return html`
<input class="form-control" required="required" type="text" name="domain" placeholder="${domain_placeholder}" />
<p class="form-text text-muted">
${i18n_providers}
<a href="${href_providers}" class="url" target="_blank" rel="noopener">${i18n_providers_link}</a>.
</p>
`;
};
const tpl_fetch_form_buttons = () => {
const i18n_register = __('Fetch registration form');
const i18n_existing_account = __('Already have a chat account?');
const i18n_login = __('Log in here');
return html`
<fieldset class="buttons">
<input class="btn btn-primary" type="submit" value="${i18n_register}" />
<div class="switch-form">
<p>${i18n_existing_account}</p>
<p><a class="login-here toggle-register-login" href="#converse/login">${i18n_login}</a></p>
</div>
</fieldset>
`;
};
const tpl_choose_provider = () => {
const default_domain = api.settings.get('registration_domain');
const i18n_create_account = __('Create your account');
const i18n_choose_provider = __('Please enter the XMPP provider to register with:');
return html`
<form id="converse-register" class="converse-form">
<legend class="col-form-label">${i18n_create_account}</legend>
<div class="form-group">
<label>${i18n_choose_provider}</label>
<div class="form-errors hidden"></div>
${default_domain ? default_domain : tpl_domain_input()}
</div>
${default_domain ? '' : tpl_fetch_form_buttons()}
</form>
`;
};
const CHOOSE_PROVIDER = 0;
const FETCHING_FORM = 1;
const REGISTRATION_FORM = 2;
export default o => {
return html`
${o.model.get('registration_status') === CHOOSE_PROVIDER ? tpl_choose_provider() : ''}
${o.model.get('registration_status') === FETCHING_FORM ? tpl_form_request(o) : ''}
${o.model.get('registration_status') === REGISTRATION_FORM ? tpl_registration_form(o) : ''}
`;
};
import { __ } from 'i18n'; import { __ } from 'i18n';
import { api } from "@converse/headless/core"; import { api } from '@converse/headless/core';
import { html } from "lit-html"; import { html } from 'lit-html';
export default (o) => { export default o => {
const i18n_choose_provider = __('Choose a different provider'); const i18n_choose_provider = __('Choose a different provider');
const i18n_has_account = __("Already have a chat account?"); const i18n_has_account = __('Already have a chat account?');
const i18n_legend = __("Account Registration:"); const i18n_legend = __('Account Registration:');
const i18n_login = __("Log in here"); const i18n_login = __('Log in here');
const i18n_register = __('Register'); const i18n_register = __('Register');
const registration_domain = api.settings.get('registration_domain') const registration_domain = api.settings.get('registration_domain');
return html` return html`
<legend class="col-form-label">${i18n_legend} ${o.domain}</legend> <form id="converse-register" class="converse-form">
<p class="title">${o.title}</p> <legend class="col-form-label">${i18n_legend} ${o.domain}</legend>
<p class="form-help instructions">${o.instructions}</p> <p class="title">${o.title}</p>
<div class="form-errors hidden"></div> <p class="form-help instructions">${o.instructions}</p>
${ o.form_fields } <div class="form-errors hidden"></div>
${o.form_fields}
<fieldset class="buttons form-group"> <fieldset class="buttons form-group">
${ o.fields ? html`<input type="submit" class="btn btn-primary" value="${i18n_register}"/>` : '' } ${o.fields
${ registration_domain ? '' : html`<input type="button" class="btn btn-secondary button-cancel" value="${i18n_choose_provider}"/>` } ? html`
<div class="switch-form"> <input type="submit" class="btn btn-primary" value="${i18n_register}" />
<p>${i18n_has_account}</p> `
<p><a class="login-here toggle-register-login" href="#converse/login">${i18n_login}</a></p> : ''}
</div> ${registration_domain
</fieldset>`; ? ''
} : html`
<input
type="button"
class="btn btn-secondary button-cancel"
value="${i18n_choose_provider}"
/>
`}
<div class="switch-form">
<p>${i18n_has_account}</p>
<p><a class="login-here toggle-register-login" href="#converse/login">${i18n_login}</a></p>
</div>
</fieldset>
</form>
`;
};
<span class="spinner login-submit fa fa-spinner"></span>
<p class="info">{{{o.__("Hold tight, we're fetching the registration form…")}}}</p>
{[ if (o.cancel) { ]}
<button class="btn btn-secondary button-cancel hor_centered">{{{o.__('Cancel')}}}</button>
{[ } ]}
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