-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Pavlo Aksonov
authored and
Pavlo Aksonov
committed
Dec 30, 2015
1 parent
6839d5b
commit def00a8
Showing
24 changed files
with
1,026 additions
and
721 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}, | ||
|
||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.