Skip to content

Commit b58d21c

Browse files
authored
Merge pull request #798 from rseemann/feature/multiplePops
[Feature/Action] Enable the popping of multiple scenes
2 parents ca82f1f + c673ed0 commit b58d21c

File tree

5 files changed

+92
-4
lines changed

5 files changed

+92
-4
lines changed

Example/Example.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Launch from './components/Launch'
44
import Register from './components/Register'
55
import Login from './components/Login'
66
import Login2 from './components/Login2'
7+
import Login3 from './components/Login3'
78
import {Scene, Reducer, Router, Switch, TabBar, Modal, Schema, Actions} from 'react-native-router-flux'
89
import Error from './components/Error'
910
import Home from './components/Home'
@@ -108,6 +109,7 @@ export default class Example extends React.Component {
108109
<Scene key="login" direction="vertical" >
109110
<Scene key="loginModal" direction="vertical" component={Login} title="Login"/>
110111
<Scene key="loginModal2" hideNavBar={true} component={Login2} title="Login2" panHandlers={null} duration={1}/>
112+
<Scene key="loginModal3" hideNavBar={true} component={Login3} title="Login3" panHandlers={null} duration={1}/>
111113
</Scene>
112114
<Scene key="tabbar" component={NavigationDrawer}>
113115
<Scene key="main" tabs={true} >

Example/components/Login2.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ const styles = StyleSheet.create({
1212
},
1313
});
1414

15-
1615
export default class extends React.Component {
1716
render(){
18-
1917
return (
2018
<View style={styles.container}>
2119
<Text>Login2 page: {this.props.data}</Text>
2220
<Button onPress={Actions.pop}>Back</Button>
21+
<Button onPress={Actions.loginModal3}>Login 3</Button>
2322
</View>
2423
);
2524
}

Example/components/Login3.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import {View, Text, StyleSheet} from "react-native";
3+
import Button from "react-native-button";
4+
import {Actions} from "react-native-router-flux";
5+
6+
const styles = StyleSheet.create({
7+
container: {
8+
flex: 1,
9+
justifyContent: "center",
10+
alignItems: "center",
11+
backgroundColor: "#F5FCFF",
12+
},
13+
});
14+
15+
const popToRoot = () => {
16+
Actions.popTo("root");
17+
}
18+
19+
const popToLogin1 = () => {
20+
Actions.popTo("loginModal");
21+
}
22+
23+
const popToLogin2 = () => {
24+
Actions.popTo("loginModal2");
25+
}
26+
27+
export default class extends React.Component {
28+
render(){
29+
return (
30+
<View style={styles.container}>
31+
<Text>Login2 page: {this.props.data}</Text>
32+
<Button onPress={Actions.pop}>Back</Button>
33+
<Button onPress={popToLogin1}>To Login</Button>
34+
<Button onPress={popToLogin2}>To Login2</Button>
35+
<Button onPress={popToRoot}>To Root</Button>
36+
</View>
37+
);
38+
}
39+
}

src/Actions.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const PUSH_ACTION = 'push';
1313
export const REPLACE_ACTION = 'replace';
1414
export const POP_ACTION2 = 'back';
1515
export const POP_ACTION = 'BackAction';
16+
export const POP_TO = 'popTo';
1617
export const REFRESH_ACTION = 'refresh';
1718
export const RESET_ACTION = 'reset';
1819
export const FOCUS_ACTION = 'focus';
@@ -32,6 +33,7 @@ function filterParam(data) {
3233
const reservedKeys = [
3334
POP_ACTION,
3435
POP_ACTION2,
36+
POP_TO,
3537
REFRESH_ACTION,
3638
REPLACE_ACTION,
3739
JUMP_ACTION,
@@ -162,6 +164,10 @@ class Actions {
162164
return res;
163165
}
164166

167+
popTo(props = {}) {
168+
return this.callback({ ...filterParam(props), type: POP_TO });
169+
}
170+
165171
pop(props = {}) {
166172
return this.callback({ ...filterParam(props), type: POP_ACTION });
167173
}

src/Reducer.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import {
1313
PUSH_ACTION,
1414
POP_ACTION2,
15+
POP_TO,
1516
JUMP_ACTION,
1617
REPLACE_ACTION,
1718
RESET_ACTION,
@@ -56,18 +57,30 @@ function inject(state, action, props, scenes) {
5657
return state;
5758
}
5859
let ind;
60+
5961
switch (action.type) {
62+
case POP_TO: {
63+
const targetIndex = action.targetIndex;
64+
65+
return {
66+
...state,
67+
index: targetIndex,
68+
children: state.children.slice(0, (targetIndex + 1)),
69+
};
70+
}
71+
6072
case POP_ACTION2:
6173
case POP_ACTION:
6274
assert(!state.tabs, 'pop() operation cannot be run on tab bar (tabs=true)');
6375
if (state.index === 0) {
6476
return state;
6577
}
78+
6679
return {
6780
...state,
6881
index: state.index - 1,
6982
from: state.children[state.children.length - 1],
70-
children: state.children.slice(0, -1),
83+
children: state.children.slice(0, - 1),
7184
};
7285
case REFRESH_ACTION:
7386
return props.base ?
@@ -203,11 +216,38 @@ function reducer({ initialState, scenes }) {
203216
} else {
204217
// set current route for pop action or refresh action
205218
if (action.type === POP_ACTION || action.type === POP_ACTION2 ||
206-
action.type === REFRESH_ACTION) {
219+
action.type === REFRESH_ACTION || action.type === POP_TO) {
207220
if (!action.key && !action.parent) {
208221
action = { ...getCurrent(state), ...action };
209222
}
210223
}
224+
225+
// Find the parent and index of the future state
226+
if (action.type === POP_TO) {
227+
const target = action.data;
228+
assert(target, 'PopTo() must be called with scene name');
229+
230+
const targetEl = findElement(state, target, action.type);
231+
assert(targetEl, `Cannot find element name named ${target} within current state`);
232+
233+
// target is a node
234+
let parent = targetEl.sceneKey;
235+
let targetIndex = 0;
236+
237+
// target is child of a node
238+
if (!targetEl.children) {
239+
const targetParent = findElement(state, targetEl.parent, action.type);
240+
assert(targetParent, `Cannot find parent for target ${target}`);
241+
parent = targetParent.sceneKey;
242+
243+
targetIndex = targetParent.children.indexOf(targetEl);
244+
assert(targetIndex > -1, `${target} does not belong to ${targetParent.sceneKey}`);
245+
}
246+
247+
action.parent = parent;
248+
action.targetIndex = targetIndex;
249+
}
250+
211251
// recursive pop parent
212252
if (action.type === POP_ACTION || action.type === POP_ACTION2) {
213253
const parent = action.parent || state.scenes[action.key].parent;
@@ -219,9 +259,11 @@ function reducer({ initialState, scenes }) {
219259
action.parent = el.sceneKey;
220260
}
221261
}
262+
222263
switch (action.type) {
223264
case POP_ACTION2:
224265
case POP_ACTION:
266+
case POP_TO:
225267
case REFRESH_ACTION:
226268
case PUSH_ACTION:
227269
case JUMP_ACTION:

0 commit comments

Comments
 (0)