Skip to content

Commit

Permalink
WIP: basic signup
Browse files Browse the repository at this point in the history
  • Loading branch information
seavan committed Oct 6, 2016
1 parent 3477475 commit 5d32785
Show file tree
Hide file tree
Showing 16 changed files with 412 additions and 22 deletions.
3 changes: 3 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ android {
}

dependencies {
compile project(':react-native-udp')
compile project(':react-native-tcp')
compile project(':react-native-randombytes')
compile project(':react-native-socketio')
compile project(':react-native-vector-icons')
compile fileTree(dir: "libs", include: ["*.jar"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import android.util.Log;

import com.facebook.react.ReactApplication;
import com.tradle.react.UdpSocketsModule;
import com.peel.react.TcpSocketsModule;
import com.bitgo.randombytes.RandomBytesPackage;
import com.gcrabtree.rctsocketio.SocketIoPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.facebook.react.ReactInstanceManager;
Expand All @@ -26,6 +29,9 @@ protected boolean getUseDeveloperSupport() {
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new UdpSocketsModule(),
new TcpSocketsModule(),
new RandomBytesPackage(),
new SocketIoPackage(),
new VectorIconsPackage()
);
Expand Down
6 changes: 6 additions & 0 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
rootProject.name = 'peeriomobile'

include ':app'
include ':react-native-udp'
project(':react-native-udp').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-udp/android')
include ':react-native-tcp'
project(':react-native-tcp').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-tcp/android')
include ':react-native-randombytes'
project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android')
include ':react-native-socketio'
project(':react-native-socketio').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-socketio/android')
include ':react-native-vector-icons'
Expand Down
1 change: 0 additions & 1 deletion app/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import DebugPanel from './layout/debugPanel';
import LayoutMain from './layout/layout-main';
import ModalContainer from './layout/modal-container';
import state from './layout/state';
import store from '../store/local-storage';
import styles from './../styles/styles';
import '../lib/icebear';
import './utils/bridge';
Expand Down
14 changes: 9 additions & 5 deletions app/components/controls/signup-footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import {
TouchableOpacity,
View
} from 'react-native';
import { observer } from 'mobx-react/native';
import { tu } from 'peerio-translator';
import signupState from '../signup/signup-state';
import styles from '../../styles/styles';

@observer
export default class SignupFooter extends Component {
constructor(props) {
super(props);
Expand All @@ -33,6 +35,12 @@ export default class SignupFooter extends Component {
}
render() {
const style = styles.wizard.footer;
const next = signupState.nextAvailable ?
<TouchableOpacity style={style.button.right} onPressIn={this.next}>
<Text style={style.button.text}>
{signupState.isLast ? tu('button_finish') : tu('continue')}
</Text>
</TouchableOpacity> : null;
return (
<View style={styles.container.footer}>
<View style={style.row}>
Expand All @@ -41,12 +49,8 @@ export default class SignupFooter extends Component {
{signupState.isFirst ? tu('button_exit') : tu('button_back')}
</Text>
</TouchableOpacity>
<TouchableOpacity style={style.button.right} onPressIn={this.next}>
<Text style={style.button.text}>
{signupState.isLast ? tu('button_finish') : tu('continue')}
</Text>
</TouchableOpacity>
</View>
{next}
</View>
);
}
Expand Down
7 changes: 5 additions & 2 deletions app/components/controls/textbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ export default class TextBox extends Component {
@observable focused = false;
@observable showSecret = false;
@observable value = '';
@observable validationMessage = null;
@observable validationMessage = '';
constructor(props) {
super(props);
this.value = this.props.value;
this.validationMessage = this.props.validationMessage;
this.blur = this.blur.bind(this);
this.focus = this.focus.bind(this);
this.changeText = this.changeText.bind(this);
Expand All @@ -38,6 +39,7 @@ export default class TextBox extends Component {
componentWillReceiveProps(nextProps) {
this.value = nextProps.value;
this.validationMessage = nextProps.validationMessage;
}
blur() {
Expand Down Expand Up @@ -83,7 +85,7 @@ export default class TextBox extends Component {
color: styles.vars.txtAlert,
fontSize: 12,
backgroundColor: 'transparent'
}}>validation error</Text>
}}>{this.validationMessage}</Text>
</View>
) : null;
return (
Expand Down Expand Up @@ -139,6 +141,7 @@ TextBox.propTypes = {
onChangeText: React.PropTypes.func.isRequired,
value: React.PropTypes.any.isRequired,
valid: React.PropTypes.bool,
validationMessage: React.PropTypes.string,
hint: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired,
secureTextEntry: React.PropTypes.bool,
Expand Down
1 change: 0 additions & 1 deletion app/components/layout/layout2.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
View
} from 'react-native';
import { observer } from 'mobx-react/native';
import state from './state';
import styles from '../../styles/styles';

@observer
Expand Down
30 changes: 29 additions & 1 deletion app/components/signup/signup-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,28 @@ import { observable, action, computed, autorun, reaction } from 'mobx';
import SignupCircles from './signup-circles';
import state from '../layout/state';
import Util from '../helpers/util';
import { User } from '../../lib/icebear';

const signupState = observable({
username: '',
usernameValid: null,
usernameValidationMessage: '',
email: '',
emailValid: null,
emailValidationMessage: 'email should contain @',
pinSaved: false,
current: 0,
count: 0,
isActive() {
return state.route.startsWith('signup');
},
@computed get nextAvailable() {
switch (signupState.current) {
case 0: return this.usernameValid;
case 1: return this.pinSaved;
default: return false;
}
},
@computed get isLast() {
return this.current === this.count - 1;
},
Expand All @@ -27,7 +38,12 @@ const signupState = observable({
state.route = 'login';
},
@action finish() {
state.routes.main.transition();
const user = new User();
user.username = signupState.username;
user.email = signupState.email;
user.passphrase = 'such a secret passphrase';
user.createAccount()
.then(state.routes.main.transition());
}
});

Expand All @@ -42,6 +58,18 @@ state.persistentFooter.signup = (i) => (signupState.isActive ? <SignupCircles ke

reaction(() => signupState.username, username => {
signupState.usernameValid = Util.isValidUsername(username);
if (username.length && !signupState.usernameValid) {
signupState.usernameValidationMessage = 'username not valid';
}
if (username.length && signupState.usernameValid) {
User.validateUsername(username)
.then(available => {
signupState.usernameValid = available;
if (!available) {
signupState.usernameValidationMessage = 'username not available';
}
});
}
});

reaction(() => signupState.email, email => {
Expand Down
4 changes: 2 additions & 2 deletions app/components/signup/signup-step1.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ export default class SignupStep1 extends Component {
<Text style={style.text.subTitle}>{t('profile')}</Text>
<TextBox
valid={signupState.usernameValid}
validationMessage={signupState.usernameValidationMessage}
{...this.tb('username', t('username'))} />
<TextBox
valid={signupState.emailValid}
validationMessage={signupState.emailValidationMessage}
{...this.tb('email', t('email'))} />
<LanguagePickerBox {...this.tb('language', t('language'))} />
<Text style={style.text.info}>
{t('signup_TOSRequestText')}
By creating a <Text style={{ fontWeight: 'bold' }}>Peerio</Text> account you agree to
our <Text style={{ textDecorationLine: 'underline' }} onPress={this.terms}>terms of service</Text>
</Text>
<View style={{ flex: 1 }} />
</View>
Expand Down
4 changes: 1 addition & 3 deletions app/components/utils/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import store from '../../store/local-storage';
import state from '../layout/state';
import loginState from '../login/login-state';
import signupState from '../signup/signup-state';
import icebear from '../../lib/icebear';

const bridge = {
store,
state,
loginState,
signupState,
icebear
signupState
};

global.Peerio = bridge;
119 changes: 119 additions & 0 deletions app/lib/btoa-shim.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* eslint-disable */
// Source: http://code.google.com/p/gflot/source/browse/trunk/flot/base64.js?r=153

/* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
* Version: 1.0
* LastModified: Dec 25 1999
* This library is free. You can redistribute it and/or modify it.
*/

/*
* Interfaces:
* b64 = base64encode(data);
* data = base64decode(b64);
*/

(function() {

var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);

function base64encode(str) {
var out, i, len;
var c1, c2, c3;

len = str.length;
i = 0;
out = "";
while(i < len) {
c1 = str.charCodeAt(i++) & 0xff;
if(i == len)
{
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if(i == len)
{
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
out += base64EncodeChars.charAt(c3 & 0x3F);
}
return out;
}

function base64decode(str) {
var c1, c2, c3, c4;
var i, len, out;

len = str.length;
i = 0;
out = "";
while(i < len) {
/* c1 */
do {
c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
} while(i < len && c1 == -1);
if(c1 == -1)
break;

/* c2 */
do {
c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
} while(i < len && c2 == -1);
if(c2 == -1)
break;

out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));

/* c3 */
do {
c3 = str.charCodeAt(i++) & 0xff;
if(c3 == 61)
return out;
c3 = base64DecodeChars[c3];
} while(i < len && c3 == -1);
if(c3 == -1)
break;

out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));

/* c4 */
do {
c4 = str.charCodeAt(i++) & 0xff;
if(c4 == 61)
return out;
c4 = base64DecodeChars[c4];
} while(i < len && c4 == -1);
if(c4 == -1)
break;
out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
}
return out;
}

var scope = global;
if (!scope.btoa) scope.btoa = base64encode;
if (!scope.atob) scope.atob = base64decode;

})();


21 changes: 17 additions & 4 deletions app/lib/icebear.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
global.navigator = window.navigator || {};
global.navigator.userAgent = window.navigator.userAgent || 'react-native';
import crypto from 'crypto';
import './btoa-shim';

global.navigator = global.navigator || {};
global.navigator.userAgent = global.navigator.userAgent || 'react-native';

global.crypto = crypto;

require('peerio-icebear');

const SocketClient = require('peerio-icebear/src/network/socket-client');
const User = require('peerio-icebear/src/models/user');

export default {
SocketClient
const icebear = {
SocketClient,
User
};

// export default icebear;
module.exports.SocketClient = SocketClient;
module.exports.User = User;

global.Icebear = icebear;
2 changes: 1 addition & 1 deletion index.ios.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* @flow
*/

import React from 'react';
import {
AppRegistry
} from 'react-native';
import './shim.js';
import App from './app/components/App';

const nicebear = () => (
Expand Down
Loading

0 comments on commit 5d32785

Please sign in to comment.