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 {
padding: 0 !important;
}
.no-scrolling {
overflow-x: none;
overflow-y: none;
}
&.converse-overlayed {
> .row {
flex-direction: row-reverse;
......
......@@ -5,7 +5,7 @@ const $iq = converse.env.$iq;
const { _, sizzle} = converse.env;
const u = converse.env.utils;
describe("The Registration Panel", function () {
fdescribe("The Registration Panel", function () {
it("is not available unless allow_registration=true",
mock.initConverse(
......
......@@ -2,9 +2,7 @@ import log from "@converse/headless/log";
import tpl_form_input from "templates/form_input.js";
import tpl_form_url from "templates/form_url.js";
import tpl_form_username from "templates/form_username.js";
import tpl_register_panel from "./templates/register_panel.html";
import tpl_registration_form from "./templates/registration_form.js";
import tpl_registration_request from "./templates/registration_request.html";
import tpl_register_panel from "./templates/register_panel.js";
import tpl_spinner from "templates/spinner.js";
import utils from "@converse/headless/utils/form";
import { View } from "@converse/skeletor/src/view";
......@@ -18,6 +16,11 @@ const { Strophe, sizzle, $iq } = converse.env;
const u = converse.env.utils;
const CHOOSE_PROVIDER = 0;
const FETCHING_FORM = 1;
const REGISTRATION_FORM = 2;
/**
* @class
* @namespace _converse.RegisterPanel
......@@ -35,29 +38,33 @@ const RegisterPanel = View.extend({
initialize () {
this.reset();
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 () {
this.model.set('registration_form_rendered', false);
this.el.innerHTML = tpl_register_panel({
'__': __,
'default_domain': api.settings.get('registration_domain'),
'label_register': __('Fetch registration form'),
'help_providers': __('Tip: A list of public XMPP providers is available'),
'help_providers_link': __('here'),
'href_providers': api.settings.get('providers_link'),
'domain_placeholder': api.settings.get('domain_placeholder')
});
if (api.settings.get('registration_domain')) {
this.fetchRegistrationForm(api.settings.get('registration_domain'));
}
render(tpl_register_panel({
'domain': this.domain,
'fields': this.fields,
'form_fields': this.form_fields,
'instructions': this.instructions,
'model': this.model,
'title': this.title,
}), this.el);
return this;
},
/**
* Hook into Strophe's _connect_cb, so that we can send an IQ
* requesting the registration fields.
*/
registerHooks () {
/* Hook into Strophe's _connect_cb, so that we can send an IQ
* requesting the registration fields.
*/
const conn = _converse.connection;
const connect_cb = conn._connect_cb.bind(conn);
conn._connect_cb = (req, callback, raw) => {
......@@ -136,7 +143,7 @@ const RegisterPanel = View.extend({
return false;
}
this.setFields(stanza);
if (!this.model.get('registration_form_rendered')) {
if (this.model.get('registration_status') === FETCHING_FORM) {
this.renderRegistrationForm(stanza);
}
return false;
......@@ -200,9 +207,7 @@ const RegisterPanel = View.extend({
* @param { String } domain_name - XMPP server domain
*/
async fetchRegistrationForm (domain_name) {
if (!this.model.get('registration_form_rendered')) {
this.renderRegistrationRequest();
}
this.model.set('registration_status', FETCHING_FORM);
this.reset({
'domain': Strophe.getDomainFromJid(domain_name),
'_registering': true
......@@ -214,21 +219,6 @@ const RegisterPanel = View.extend({
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) {
let feedback = this.el.querySelector('.reg-feedback');
if (feedback !== null) {
......@@ -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 () {
const form = this.el.querySelector('form');
render(tpl_spinner(), form);
this.model.set('registration_form_rendered', false);
return this;
},
......@@ -346,17 +328,8 @@ const RegisterPanel = View.extend({
* @param { XMLElement } stanza - The IQ stanza received from the XMPP server.
*/
renderRegistrationForm (stanza) {
const form = this.el.querySelector('form');
const tpl = tpl_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);
this.form_fields = this.getFormFields(stanza);
this.model.set('registration_status', REGISTRATION_FORM);
},
showValidationError (message) {
......@@ -408,11 +381,9 @@ const RegisterPanel = View.extend({
abortRegistration () {
_converse.connection._proto._abortAllRequests();
_converse.connection.reset();
if (this.model.get('registration_form_rendered')) {
if (api.settings.get('registration_domain') && this.model.get('registration_form_rendered')) {
this.fetchRegistrationForm(
api.settings.get('registration_domain')
);
if ([FETCHING_FORM, REGISTRATION_FORM].includes(this.model.get('registration_status'))) {
if (api.settings.get('registration_domain')) {
this.fetchRegistrationForm(api.settings.get('registration_domain'));
}
} else {
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 { api } from "@converse/headless/core";
import { html } from "lit-html";
import { api } from '@converse/headless/core';
import { html } from 'lit-html';
export default (o) => {
export default o => {
const i18n_choose_provider = __('Choose a different provider');
const i18n_has_account = __("Already have a chat account?");
const i18n_legend = __("Account Registration:");
const i18n_login = __("Log in here");
const i18n_has_account = __('Already have a chat account?');
const i18n_legend = __('Account Registration:');
const i18n_login = __('Log in here');
const i18n_register = __('Register');
const registration_domain = api.settings.get('registration_domain')
const registration_domain = api.settings.get('registration_domain');
return html`
<legend class="col-form-label">${i18n_legend} ${o.domain}</legend>
<p class="title">${o.title}</p>
<p class="form-help instructions">${o.instructions}</p>
<div class="form-errors hidden"></div>
${ o.form_fields }
<form id="converse-register" class="converse-form">
<legend class="col-form-label">${i18n_legend} ${o.domain}</legend>
<p class="title">${o.title}</p>
<p class="form-help instructions">${o.instructions}</p>
<div class="form-errors hidden"></div>
${o.form_fields}
<fieldset class="buttons form-group">
${ o.fields ? html`<input type="submit" class="btn btn-primary" value="${i18n_register}"/>` : '' }
${ registration_domain ? '' : 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>`;
}
<fieldset class="buttons form-group">
${o.fields
? html`
<input type="submit" class="btn btn-primary" value="${i18n_register}" />
`
: ''}
${registration_domain
? ''
: 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