diff --git a/app/assets/styles/blink/_EnrollmentModal.scss b/app/assets/styles/blink/_EnrollmentModal.scss
index 9ad2185..441520e 100644
--- a/app/assets/styles/blink/_EnrollmentModal.scss
+++ b/app/assets/styles/blink/_EnrollmentModal.scss
@@ -1,28 +1,49 @@
+.container {
+}
+
+.landscape {
+ height: 200px;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.landscapeTablet {
+ height: 200px;
+ margin-bottom: 10px;
+ margin-top: 10px;
+}
+
+.portrait {
+ height: 300px;
+ margin-bottom: 10px;
+ margin-top: 10px;
+}
+
+.portraitTablet {
+ height: 400px;
+ margin-bottom: 10px;
+ margin-top: 10px;
+}
+
.title {
- padding-top: 00px;
+ margin-top: 0px;
color: black;
margin: 0 auto;
- font-size: 18;
+ font-size: 16;
}
.row {
- color: black;
font-size: 14;
}
-.container {
-}
-
-.inner {
- // flex: 1;
- // justify-content: flex-end;
+.snackbar {
}
.button {
margin-top: 0px;
border-radius: 1px;
border: 0px;
margin: 0 auto;
- margin-top: 20px;
- margin-bottom: 20px;
+ margin-top: 10px;
+ margin-bottom: 10px;
}
diff --git a/app/components/EnrollmentModal.js b/app/components/EnrollmentModal.js
index 6d2e441..bee99d5 100644
--- a/app/components/EnrollmentModal.js
+++ b/app/components/EnrollmentModal.js
@@ -1,264 +1,289 @@
import React, { Component } from 'react';
import { View, KeyboardAvoidingView, Platform, ScrollView } from 'react-native';
import PropTypes from 'prop-types';
import superagent from 'superagent';
import autoBind from 'auto-bind';
-import { Dialog, Portal, Button, TextInput, Title, Surface, HelperText, Snackbar } from 'react-native-paper';
+import { Dialog, Portal, Button, TextInput, Text, Title, Surface, HelperText, Snackbar } from 'react-native-paper';
import KeyboardAwareDialog from './KeyBoardAwareDialog';
import LoadingScreen from './LoadingScreen';
const DialogType = Platform.OS === 'ios' ? KeyboardAwareDialog : Dialog;
import styles from '../assets/styles/blink/_EnrollmentModal.scss';
import config from '../config';
class EnrollmentModal extends Component {
constructor(props) {
super(props);
autoBind(this);
// save the initial state so we can restore it later
this.initialState = {
displayName: '',
username: '',
password: '',
password2: '',
email: '',
enrolling: false,
error: '',
errorVisible: false
};
this.state = Object.assign({}, this.initialState);
}
handleFormFieldChange(value, name) {
- ///^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/;
if (name === 'username') {
value = value.replace(/[^\w|\.\-]/g, '').trim().toLowerCase();
}
this.setState({
[name]: value
});
}
get validInput() {
let valid_input = !this.state.enrolling;
let error;
valid_input = valid_input && this.state.displayName.length > 2;
if (!valid_input && !error) {
error = 'Invalid display name';
}
valid_input = valid_input && this.state.username.length > 3;
if (!valid_input && !error) {
error = 'Invalid username';
}
valid_input = valid_input && this.state.password !== '';
if (!valid_input && !error) {
error = 'Invalid password';
}
valid_input = valid_input && this.state.password === this.state.password2;
if (!valid_input && !error) {
error = 'Passwords not equal';
}
valid_input = valid_input && this.state.email.indexOf('@') > -1;
if (!valid_input && !error) {
error = 'Email not valid';
}
if (!valid_input) {
//console.log(error);
}
return valid_input;
}
enroll(event) {
event.preventDefault();
this.setState({enrolling: true, error:''});
superagent.post(config.enrollmentUrl)
.send(superagent.serialize['application/x-www-form-urlencoded']({username: this.state.username,
password: this.state.password,
email: this.state.email,
phoneNumber: this.props.phoneNumber,
display_name: this.state.displayName})) //eslint-disable-line camelcase
.end((error, res) => {
this.setState({enrolling: false});
if (error) {
this.setState({error: error.toString(), errorVisible: true});
return;
}
let data;
try {
data = JSON.parse(res.text);
} catch (e) {
this.setState({error: 'Could not decode response data', errorVisible: true});
return;
}
if (data.success) {
this.props.handleEnrollment({id: data.sip_address,
password: this.state.password,
displayName: this.state.displayName,
email: this.state.email});
this.setState(this.initialState);
} else if (data.error === 'user_exists') {
this.setState({error: 'Username is taken. Choose another one!', errorVisible: true});
} else {
this.setState({error: data.error_message, errorVisible: true});
}
});
}
onHide() {
this.props.handleEnrollment(null);
this.setState(this.initialState);
}
render() {
let buttonText = 'Sign Up';
let buttonIcon = null;
let loadingText = 'Enrolling...';
+ let containerClass;
if (this.state.enrolling) {
buttonIcon = "cog";
}
+ if (this.props.isTablet) {
+ containerClass = this.props.orientation === 'landscape' ? styles.landscapeTablet : styles.portraitTablet;
+ } else {
+ containerClass = this.props.orientation === 'landscape' ? styles.landscape : styles.portrait;
+ }
+
let email_reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/;
let validEmail = email_reg.test(this.state.email);
let validUsername = this.state.username.length > 3;
return (
- Create account
+ Sign Up
+ {
+ this.scrollView = ref;
+ }}
+
+ style={containerClass}>
+
{this.handleFormFieldChange(text, 'displayName');}}
required
value={this.state.displayName}
disabled={this.state.enrolling}
returnKeyType="next"
onSubmitEditing={() => this.emailInput ? this.emailInput.focus() : null}
/>
- { this.state.displayName.length > 2 ?
+ { this.state.displayName.length > 2 || true ?
{this.handleFormFieldChange(text, 'email');}}
required value={this.state.email}
disabled={this.state.enrolling}
returnKeyType="go"
ref={ref => {
this.emailInput = ref;
}}
- onSubmitEditing={() => this.usernameInput ? this.usernameInput.focus() : null}
+ onSubmitEditing={() => this.usernameInput && validEmail ? this.usernameInput.focus() : null}
/>
:
null }
- { validEmail?
+ { validEmail || true?
{this.handleFormFieldChange(text, 'username');}}
required
value={this.state.username}
disabled={this.state.enrolling}
returnKeyType="next"
ref={ref => {
this.usernameInput = ref;
}}
- onSubmitEditing={() => this.passwordInput ? this.passwordInput.focus(): null}
+ onSubmitEditing={() => validUsername && this.passwordInput ? this.passwordInput.focus(): null}
/>
: null}
- { validUsername ?
+ { validUsername ?
{this.handleFormFieldChange(text, 'password');}}
required value={this.state.password}
disabled={this.state.enrolling}
returnKeyType="next"
ref={ref => {
this.passwordInput = ref;
}}
- onSubmitEditing={() => this.password2Input ? this.password2Input.focus(): null}
+ onSubmitEditing={() => this.state.password.length > 4 && this.password2Input ? this.password2Input.focus(): null}
/>
: null}
- { validUsername ?
+ { validUsername ?
{this.handleFormFieldChange(text, 'password2');}}
+ onSubmitEditing={() => this.scrollView.scrollToEnd()}
required value={this.state.password2}
disabled={this.state.enrolling}
returnKeyType="next"
ref={ref => {
this.password2Input = ref;
}}
/>
: null}
+ {this.validInput ?
+
- {buttonText}
+
+
+ }
+
+ this.setState({ errorVisible: false })}
>
{this.state.error}
+
);
}
}
EnrollmentModal.propTypes = {
handleEnrollment: PropTypes.func.isRequired,
show: PropTypes.bool.isRequired,
- phoneNumber : PropTypes.string
+ phoneNumber : PropTypes.string,
+ orientation : PropTypes.string,
+ isTablet : PropTypes.bool
};
export default EnrollmentModal;
diff --git a/app/components/RegisterBox.js b/app/components/RegisterBox.js
index e6c0a6f..4e10be7 100644
--- a/app/components/RegisterBox.js
+++ b/app/components/RegisterBox.js
@@ -1,55 +1,54 @@
import React from 'react';
import { View, Text } from 'react-native';
import PropTypes from 'prop-types';
import RegisterForm from './RegisterForm';
import Logo from './Logo';
import styles from '../assets/styles/blink/_RegisterBox.scss';
const RegisterBox = (props) => {
let containerClass;
if (props.isTablet) {
containerClass = props.orientation === 'landscape' ? styles.landscapeTabletRegisterBox : styles.portraitTabletRegisterBox;
} else {
containerClass = props.orientation === 'landscape' ? styles.landscapeRegisterBox : styles.portraitRegisterBox;
}
-
return (
);
};
RegisterBox.propTypes = {
handleRegistration : PropTypes.func.isRequired,
handleEnrollment : PropTypes.func.isRequired,
registrationInProgress : PropTypes.bool,
autoLogin : PropTypes.bool,
orientation : PropTypes.string,
isTablet : PropTypes.bool,
phoneNumber : PropTypes.string
};
export default RegisterBox;
diff --git a/app/components/RegisterForm.js b/app/components/RegisterForm.js
index 0082944..14ecde5 100644
--- a/app/components/RegisterForm.js
+++ b/app/components/RegisterForm.js
@@ -1,205 +1,207 @@
import React, { Component } from 'react';
import { View, Text, Linking, Keyboard } from 'react-native';
import PropTypes from 'prop-types';
import ipaddr from 'ipaddr.js';
import autoBind from 'auto-bind';
import FooterBox from './FooterBox';
import { Button, TextInput, Title, Subheading } from 'react-native-paper';
import EnrollmentModal from './EnrollmentModal';
import storage from '../storage';
import config from '../config';
import styles from '../assets/styles/blink/_RegisterForm.scss';
function isASCII(str) {
return /^[\x00-\x7F]*$/.test(str);
}
function handleLink(event) {
let link = 'https://mdns.sipthor.net/sip_login_reminder.phtml';
storage.get('last_signup').then((last_signup) => {
if (last_signup) {
storage.get('signup').then((signup) => {
if (signup) {
let email = signup[last_signup];
link = link + '?sip_filter=' + last_signup + '&email_filter=' + email;
}
console.log('Opening link', link);
Linking.openURL(link);
});
} else {
console.log('Opening link', link);
Linking.openURL(link);
}
});
}
class RegisterForm extends Component {
constructor(props) {
super(props);
autoBind(this);
this.state = {
accountId: '',
password: '',
registering: false,
remember: false,
showEnrollmentModal: false
};
}
componentDidMount() {
storage.get('account').then((account) => {
if (account) {
this.setState(Object.assign({}, account));
if (this.props.autoLogin && this.state.password !== '') {
this.props.handleRegistration(this.state.accountId, this.state.password);
}
}
});
}
handleAccountIdChange(value) {
this.setState({accountId: value.trim()});
}
handlePasswordChange(value) {
this.setState({password: value.trim()});
}
handleSubmit(event) {
if (!this.validInput()) {
return;
}
if (event) {
event.preventDefault();
}
let account = this.state.accountId;
if (this.state.accountId.indexOf('@') === -1 ) {
account = this.state.accountId + '@' + config.defaultDomain;
}
Keyboard.dismiss();
this.props.handleRegistration(account, this.state.password);
}
handleEnrollment(account) {
this.setState({showEnrollmentModal: false});
if (account) {
this.setState({accountId: account.id, password: account.password, registering: true});
this.props.handleEnrollment(account);
}
}
createAccount(event) {
event.preventDefault();
this.setState({showEnrollmentModal: true});
}
validInput() {
const domain = this.state.accountId.indexOf('@') !== -1 ? this.state.accountId.substring(this.state.accountId.indexOf('@') + 1): '';
const validDomain = domain === '' || (!ipaddr.IPv4.isValidFourPartDecimal(domain) && !ipaddr.IPv6.isValid(domain) && domain.length > 3 && domain.indexOf('.') !== - 1 && (domain.length - 2 - domain.indexOf('.')) > 0);
const validInput = isASCII(this.state.accountId) && validDomain && this.state.password !== '' && isASCII(this.state.password);
return validInput;
}
render() {
let containerClass;
if (this.props.isTablet) {
containerClass = this.props.orientation === 'landscape' ? styles.landscapeTabletContainer : styles.portraitTabletContainer;
} else {
containerClass = this.props.orientation === 'landscape' ? styles.landscapeContainer : styles.portraitContainer;
}
return (
Sylk
Sign in to continue
this.passwordInput.focus()}
/>
{
this.passwordInput = ref;
}}
/>
{ config.enrollmentUrl ?
: null }
handleLink()} style={styles.recoverLink}>Recover lost passsword...
);
}
}
RegisterForm.propTypes = {
classes : PropTypes.object,
handleRegistration : PropTypes.func.isRequired,
handleEnrollment : PropTypes.func.isRequired,
registrationInProgress : PropTypes.bool.isRequired,
autoLogin : PropTypes.bool,
orientation : PropTypes.string,
isTablet : PropTypes.bool,
phoneNumber : PropTypes.string
};
export default RegisterForm;