Skip to content

Commit

Permalink
new 2.0(alpha) version
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavlo Aksonov authored and Pavlo Aksonov committed Dec 30, 2015
1 parent 6839d5b commit def00a8
Show file tree
Hide file tree
Showing 24 changed files with 1,026 additions and 721 deletions.
90 changes: 90 additions & 0 deletions Actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import Route from './Route';
import Router from './Router';

function isNumeric(n){
return !isNaN(parseFloat(n)) && isFinite(n);
}

function filterParam(data){
if (data.toString()!='[object Object]')
return data;
if (!data){
return;
}
var proto = (data||{}).constructor.name;
// avoid passing React Native parameters
if (proto != 'Object'){
data = {};
}
if (data.data){
data.data = filterParam(data.data);
}
return data;
}

class Actions {
currentRouter: ?Router;

constructor(){
this.pop = this.pop.bind(this);
this.route = this.route.bind(this);
}

route(name: string, props: { [key: string]: any} = {}){
if (!this.currentRouter){
throw new Error("No current router is set");
}
if (props.toString()!='[object Object]')
props = {data : props};

props = filterParam(props);
// check if route is in children, current or parent routers
let router: Router = this.currentRouter;
// deep into child router
while (router.currentRoute.childRouter){
router = router.currentRoute.childRouter;
}
while (!router.routes[name]){
const route = router.parentRoute;
if (!route || !route.parent){
throw new Error("Cannot find router for route="+name);
}
router = route.parent;
}
if (router.route(name, props)){
this.currentRouter = router;
return true;
}
return false;
}
pop(num: number = 1){
if (!isNumeric(num)){
num = 1;
}
if (!this.currentRouter){
throw new Error("No current router is set");
}
if (num > 1){
for (let i=0;i<num;i++){
if (!Actions.pop()){
return false;
}
}
return true;
} else {
let router: Router = this.currentRouter;
while (router.stack.length <= 1 || router.currentRoute.type === 'switch'){
router = router.parentRoute.parent;
}
if (router.pop()){
this.currentRouter = router;
return true;
} else {
return false;
}

}
}
}

export default new Actions();
23 changes: 23 additions & 0 deletions Common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react-native';

// schema class represents schema for routes and it is processed inside Router component
export class Schema extends React.Component {
className(){
return "Schema";
}
render(){
return null;
}
}

// route class processed inside Router component
export class Route extends React.Component {
className(){
return "Route";
}
render(){
return null;
}

}

171 changes: 171 additions & 0 deletions ExRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import React from 'react-native';
import Router from './Router';
import Route from './Route';
import * as Components from './Common';
import ExNavigator from '@exponent/react-native-navigator';
import Animations from './Animations';
const {TouchableOpacity, StyleSheet, View, Text} = React;
import ReactRouter from './ReactRouter';

export class ExRoute {
name: string;
navigator: ExNavigator;
route: Route;
props: { [key: string]: any};

constructor(route: Route, props:{ [key: string]: any} = {}){
if (!route){
throw new Error("route is not defined ");
}
this.route = route;
this.name = route.name;
if (!this.name){
throw new Error("name is not defined for route");
}
this.props = props;
this.renderScene = this.renderScene.bind(this);
}

configureScene() {
return this.route.type === 'switch' ? Animations.None : this.route.props.sceneConfig || Animations.None;
}

renderScene(navigator) {
console.log("RENDER SCENE:"+this.route.name);
const Component = this.route.component;
const child = Component ?
!this.route.wrapRouter ? <Component key={this.route.name} name={this.route.name} {...this.route.props} {...this.props} route={this.route}/>:
<ReactRouter name={this.route.name+"Router"} {...this.route.props} {...this.props} route={this.route} router={ExRouter} >
<Components.Route {...this.route.props} {...this.props} component={Component} name={"_"+this.route.name} type="push" wrapRouter={false}/>
</ReactRouter>
:
React.cloneElement(React.Children.only(this.route.children), {...this.route.props, data:this.props, route:this.route});
return child;
}

getName(){
return this.route.name;
}

getTitle() {
return this.route.title || "";
}

getBackButtonTitle(navigator, index, state){
let previousIndex = index - 1;
let previousRoute = state.routeStack[previousIndex];
let title = previousRoute.getTitle(navigator, previousIndex, state);
return title.length>10 ? null : title;
}

renderRightButton() {
if (this.route.onRight && this.route.rightTitle){
return (<TouchableOpacity
touchRetentionOffset={ExNavigator.Styles.barButtonTouchRetentionOffset}
onPress={() => this.route.onRight({...this.route.props, ...this.props})}
style={[ExNavigator.Styles.barRightButton, this.route.rightButtonStyle]}>
<Text style={[ExNavigator.Styles.barRightButtonText, this.route.rightButtonTextStyle]}>{this.route.rightTitle}</Text>
</TouchableOpacity>);
} else {
return null;
}
}
}

const defaultCreateRoute = function(route, data){
return new ExRoute(route, data);
};

export default class ExRouter extends React.Component {
router: Router;

constructor(props){
super(props);
this.onPop = this.onPop.bind(this);
this.onPush = this.onPush.bind(this);
this.onPop = this.onPop.bind(this);
this.onPush = this.onPush.bind(this);
this.onReplace = this.onReplace.bind(this);
this.onJump = this.onJump.bind(this);
}

onPush(route: Route, props:{ [key: string]: any}):boolean {
this.refs.nav.push(new ExRoute(route, props));
return true;
}

onReplace(route: Route, props:{ [key: string]: any}):boolean {
this.refs.nav.replace(new ExRoute(route, props));
return true;
}

onJump(route: Route, props:{ [key: string]: any}):boolean {
const navigator = this.refs.nav;
const routes = navigator.getCurrentRoutes();
const exist = routes.filter(el=>el.getName()==route.name);
if (exist.length){
navigator.jumpTo(exist[0]);
} else {
navigator.push(new ExRoute(route, props));

}
this.setState({selected: route.name});
return true;
}

onPop(num: number){
this.refs.nav.pop();
return true;
}

render() {
const router = this.props.router;
console.log("RE-RENDER selected",router.name,this.state && this.state.selected);

const Header = this.props.header;
const header = Header ? <Header {...this.props} {...this.state}/> : null;

const Footer = this.props.footer;
const footer = Footer ? <Footer {...this.props} {...this.state}/> : null;

return (
<View style={styles.transparent}>
{header}
<ExNavigator ref="nav" initialRouteStack={router.stack.map(route => new ExRoute(router.routes[route]))}
style={styles.transparent}
sceneStyle={{ paddingTop: 0 }}
showNavigationBar={!this.props.hideNavBar}
{...this.props}
/>
{footer}
</View>
);
}


}


var styles = StyleSheet.create({
container: {
position: 'absolute',
top:0,
bottom:0,
left:0,
right:0,
backgroundColor:'transparent',
justifyContent: 'center',
alignItems: 'center',
},
transparent: {
flex:1,
backgroundColor: "transparent"
},
barTitleText: {
fontFamily: '.HelveticaNeueInterface-MediumP4',
fontSize: 17,
marginTop: 11,
},

});

43 changes: 23 additions & 20 deletions Example/Example.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
'use strict';

var React = require('react-native');
var {AppRegistry, Navigator, StyleSheet,Text,View} = React;
var Launch = require('./components/Launch');
var Register = require('./components/Register');
var Login = require('./components/Login');
var Login2 = require('./components/Login2');
var {Router, Route, Schema, Animations, TabBar} = require('react-native-router-flux');
var Error = require('./components/Error');
var Home = require('./components/Home');
var TabView = require('./components/TabView');
import React from 'react-native';
import {Schema, Route, TabBar, Router} from 'react-native-router-flux';
const {Navigator, Text} = React;
import Launch from './components/Launch';
import Register from './components/Register';
import Login from './components/Login';
import Login2 from './components/Login2';
import Home from './components/Home';
import TabView from './components/TabView';

class TabIcon extends React.Component {
render(){
Expand All @@ -22,34 +20,39 @@ class TabIcon extends React.Component {
export default class Example extends React.Component {
render() {
return (
<Router hideNavBar={true} initialRoutes={['launch']}>
<Router name="root" hideNavBar={true} initialRoutes={['launch']}>
<Schema name="modal" sceneConfig={Navigator.SceneConfigs.FloatFromBottom}/>
<Schema name="default" sceneConfig={Navigator.SceneConfigs.FloatFromRight}/>
<Schema name="withoutAnimation"/>
<Schema name="tab" type="switch" icon={TabIcon} />
<Schema name="tab" type="switch"/>

<Route name="launch" component={Launch} wrapRouter={true} title="Launch" hideNavBar={true}/>
<Route name="register" component={Register} title="Register"/>
<Route name="home" component={Home} title="Replace" type="replace"/>
<Route name="login" schema="modal">
<Router>
<Router name="loginRouter">
<Route name="loginModal" component={Login} title="Login" schema="modal"/>
<Route name="loginModal2" component={Login2} title="Login2"/>
</Router>
</Route>
<Route name="register2" component={Register} title="Register2" schema="withoutAnimation"/>
<Route name="tabbar">
<Router footer={TabBar} showNavigationBar={false}>
<Route name="tab1" schema="tab" title="Tab #1" >
<Router name="tabbar" footer={TabBar} showNavigationBar={false}>
<Route name="tab1" icon={TabIcon} schema="tab" title="Tab #1" >
<Router>
<Route name="tab1_1" component={TabView} title="Tab #1_1" />
<Route name="tab1_2" component={TabView} title="Tab #1_2" />
</Router>
</Route>
<Route name="tab2" schema="tab" title="Tab #2" hideTabBar={true} component={TabView} />
<Route name="tab3" schema="tab" title="Tab #3" component={TabView} />
<Route name="tab4" schema="tab" title="Tab #4" component={TabView} />
<Route name="tab5" schema="tab" title="Tab #5" component={TabView} />
<Route name="tab2" icon={TabIcon} schema="tab" title="Tab #2" hideTabBar={true} component={TabView} />
<Route name="tab3" icon={TabIcon} schema="tab" title="Tab #3">
<Router>
<Route name="tab3_1" component={TabView} title="Tab #3_1" />
<Route name="tab3_2" component={TabView} title="Tab #3_2" />
</Router>
</Route>
<Route name="tab4" icon={TabIcon} schema="tab" title="Tab #4" component={TabView} />
<Route name="tab5" icon={TabIcon} schema="tab" title="Tab #5" component={TabView} />
</Router>
</Route>
</Router>
Expand Down
2 changes: 1 addition & 1 deletion Example/components/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Login extends React.Component {
render(){
return (
<View style={styles.container}>
<Text>Login page: {this.props.data}</Text>
<Text>Login page: {JSON.stringify(this.props.data)}</Text>
<Button onPress={Actions.loginModal2}>Login 2</Button>
<Button onPress={Actions.pop}>Back</Button>
</View>
Expand Down
2 changes: 1 addition & 1 deletion Example/components/Login2.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Login extends React.Component {
render(){
return (
<View style={styles.container}>
<Text>Login2 page: {this.props.data}</Text>
<Text>Login2 page</Text>
<Button onPress={Actions.pop}>Back</Button>
</View>
);
Expand Down
14 changes: 0 additions & 14 deletions Example/components/TabIcon.js

This file was deleted.

Loading

0 comments on commit def00a8

Please sign in to comment.