Daniel Zlotin 7 years ago
parent
commit
db93d204d1

+ 3
- 3
lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java View File

47
 		handle(new Runnable() {
47
 		handle(new Runnable() {
48
 			@Override
48
 			@Override
49
 			public void run() {
49
 			public void run() {
50
-				final LayoutNode layoutTree = LayoutNodeParser.parse(JSONParser.parse(rawLayoutTree));
51
-				final ViewController viewController = newLayoutFactory().create(layoutTree);
52
-//				store.getViewController(onContainerId).getStackController().push(viewController);
50
+//				final LayoutNode layoutTree = LayoutNodeParser.parse(JSONParser.parse(rawLayoutTree));
51
+//				final ViewController viewController = newLayoutFactory().create(layoutTree);
52
+////				store.getViewController(onContainerId).getStackController().push(viewController);
53
 			}
53
 			}
54
 		});
54
 		});
55
 	}
55
 	}

+ 36
- 0
lib/android/app/src/main/java/com/reactnativenavigation/utils/IdStack.java View File

1
+package com.reactnativenavigation.utils;
2
+
3
+import java.util.ArrayDeque;
4
+import java.util.HashMap;
5
+
6
+public class IdStack<E> {
7
+
8
+	private final ArrayDeque<String> deque = new ArrayDeque<>();
9
+	private final HashMap<String, E> map = new HashMap<>();
10
+
11
+	public void push(String id, E item) {
12
+		deque.push(id);
13
+		map.put(id, item);
14
+	}
15
+
16
+	public E peek() {
17
+		return map.get(deque.peek());
18
+	}
19
+
20
+	public E pop() {
21
+		if (deque.isEmpty()) {
22
+			return null;
23
+		}
24
+		String popped = deque.pop();
25
+		E removed = map.remove(popped);
26
+		return removed;
27
+	}
28
+
29
+	public boolean isEmpty() {
30
+		return deque.isEmpty();
31
+	}
32
+
33
+	public int size() {
34
+		return deque.size();
35
+	}
36
+}

+ 12
- 0
lib/android/app/src/main/java/com/reactnativenavigation/utils/StringUtils.java View File

1
+package com.reactnativenavigation.utils;
2
+
3
+public class StringUtils {
4
+
5
+	@SuppressWarnings("StringEquality")
6
+	public static boolean isEqual(String s1, String s2) {
7
+		if (s1 == null || s2 == null) {
8
+			return s1 == s2;
9
+		}
10
+		return s1.equals(s2);
11
+	}
12
+}

+ 9
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/Navigator.java View File

9
 
9
 
10
 public class Navigator extends ViewController {
10
 public class Navigator extends ViewController {
11
 	private boolean activityResumed = false;
11
 	private boolean activityResumed = false;
12
+	private ViewController child;
12
 
13
 
13
 	public Navigator(final Activity activity) {
14
 	public Navigator(final Activity activity) {
14
 		super(activity, "navigator" + CompatUtils.generateViewId());
15
 		super(activity, "navigator" + CompatUtils.generateViewId());
49
 
50
 
50
 	public void onActivityDestroyed() {
51
 	public void onActivityDestroyed() {
51
 	}
52
 	}
53
+
54
+	public void push(final ViewController onViewController, final ViewController viewController) {
55
+
56
+	}
57
+
58
+	public ViewController getViewController(final String id) {
59
+		return null;
60
+	}
52
 }
61
 }

+ 31
- 15
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/StackController.java View File

6
 import android.view.ViewGroup;
6
 import android.view.ViewGroup;
7
 import android.widget.FrameLayout;
7
 import android.widget.FrameLayout;
8
 
8
 
9
+import com.reactnativenavigation.utils.StringUtils;
10
+
9
 import java.util.ArrayDeque;
11
 import java.util.ArrayDeque;
12
+import java.util.HashMap;
13
+import java.util.Map;
10
 
14
 
11
 public class StackController extends ViewController {
15
 public class StackController extends ViewController {
12
-	private final ArrayDeque<ViewController> stack = new ArrayDeque<>();
16
+	private final ArrayDeque<String> idStack = new ArrayDeque<>();
17
+	private final Map<String, ViewController> controllersById = new HashMap<>();
13
 
18
 
14
 	public StackController(final Activity activity, String id) {
19
 	public StackController(final Activity activity, String id) {
15
 		super(activity, id);
20
 		super(activity, id);
19
 		final ViewController previousTop = peek();
24
 		final ViewController previousTop = peek();
20
 
25
 
21
 		child.setStackController(this);
26
 		child.setStackController(this);
22
-		stack.push(child);
27
+		idStack.push(child.getId());
28
+		controllersById.put(child.getId(), child);
23
 
29
 
24
 		getView().addView(child.getView());
30
 		getView().addView(child.getView());
25
 		if (previousTop != null) {
31
 		if (previousTop != null) {
28
 	}
34
 	}
29
 
35
 
30
 	public boolean canPop() {
36
 	public boolean canPop() {
31
-		return stack.size() > 1;
37
+		return idStack.size() > 1;
32
 	}
38
 	}
33
 
39
 
34
 	public void pop() {
40
 	public void pop() {
35
 		if (!canPop()) {
41
 		if (!canPop()) {
36
 			return;
42
 			return;
37
 		}
43
 		}
38
-		ViewController poppedController = stack.pop();
44
+		String poppedId = idStack.pop();
45
+		ViewController poppedController = controllersById.remove(poppedId);
39
 		getView().removeView(poppedController.getView());
46
 		getView().removeView(poppedController.getView());
40
 
47
 
41
 		ViewController previousTop = peek();
48
 		ViewController previousTop = peek();
43
 	}
50
 	}
44
 
51
 
45
 	public void pop(final ViewController childController) {
52
 	public void pop(final ViewController childController) {
46
-		if (peek() == childController) {
53
+		if (StringUtils.isEqual(peekId(), childController.getId())) {
47
 			pop();
54
 			pop();
48
 		} else {
55
 		} else {
49
-			stack.remove(childController);
56
+			idStack.remove(childController.getId());
57
+			controllersById.remove(childController.getId());
50
 		}
58
 		}
51
 	}
59
 	}
52
 
60
 
53
 	public ViewController peek() {
61
 	public ViewController peek() {
54
-		return stack.peek();
62
+		return controllersById.get(peekId());
63
+	}
64
+
65
+	public String peekId() {
66
+		return idStack.peek();
55
 	}
67
 	}
56
 
68
 
57
 	public int size() {
69
 	public int size() {
58
-		return stack.size();
70
+		return idStack.size();
59
 	}
71
 	}
60
 
72
 
61
 	public boolean isEmpty() {
73
 	public boolean isEmpty() {
62
-		return stack.isEmpty();
74
+		return idStack.isEmpty();
63
 	}
75
 	}
64
 
76
 
65
 	@Override
77
 	@Override
90
 		return this;
102
 		return this;
91
 	}
103
 	}
92
 
104
 
93
-	ArrayDeque<ViewController> getStack() {
94
-		return stack;
95
-	}
96
-
97
 	public void popTo(final ViewController viewController) {
105
 	public void popTo(final ViewController viewController) {
98
-		if (!stack.contains(viewController)) {
106
+		if (!idStack.contains(viewController.getId())) {
99
 			return;
107
 			return;
100
 		}
108
 		}
101
-		while (peek() != viewController) {
109
+		while (!StringUtils.isEqual(peekId(), viewController.getId())) {
102
 			pop();
110
 			pop();
103
 		}
111
 		}
104
 	}
112
 	}
108
 			pop();
116
 			pop();
109
 		}
117
 		}
110
 	}
118
 	}
119
+
120
+	public ViewController getChildById(final String id) {
121
+		return controllersById.get(id);
122
+	}
123
+
124
+	ArrayDeque<String> getStack() {
125
+		return idStack;
126
+	}
111
 }
127
 }

+ 48
- 0
lib/android/app/src/test/java/com/reactnativenavigation/utils/IdStackTest.java View File

1
+package com.reactnativenavigation.utils;
2
+
3
+import com.reactnativenavigation.BaseTest;
4
+
5
+import org.junit.Test;
6
+
7
+import static org.assertj.core.api.Java6Assertions.assertThat;
8
+
9
+public class IdStackTest extends BaseTest {
10
+
11
+	private IdStack<Integer> uut;
12
+
13
+	@Override
14
+	public void beforeEach() {
15
+		super.beforeEach();
16
+		uut = new IdStack<>();
17
+	}
18
+
19
+	@Test
20
+	public void isEmpty() throws Exception {
21
+		assertThat(uut.isEmpty()).isTrue();
22
+		uut.push("123", 123);
23
+		assertThat(uut.isEmpty()).isFalse();
24
+	}
25
+
26
+	@Test
27
+	public void size() throws Exception {
28
+		assertThat(uut.size()).isEqualTo(0);
29
+		uut.push("123", 123);
30
+		assertThat(uut.size()).isEqualTo(1);
31
+	}
32
+
33
+	@Test
34
+	public void peek() throws Exception {
35
+		assertThat(uut.peek()).isNull();
36
+		uut.push("123", 123);
37
+		uut.push("456", 456);
38
+		assertThat(uut.peek()).isEqualTo(456);
39
+	}
40
+
41
+	@Test
42
+	public void pop() throws Exception {
43
+		assertThat(uut.pop()).isNull();
44
+		uut.push("123", 123);
45
+		uut.push("456", 456);
46
+		assertThat(uut.pop()).isEqualTo(456);
47
+	}
48
+}

+ 19
- 0
lib/android/app/src/test/java/com/reactnativenavigation/utils/StringUtilsTest.java View File

1
+package com.reactnativenavigation.utils;
2
+
3
+import com.reactnativenavigation.BaseTest;
4
+
5
+import org.junit.Test;
6
+
7
+import static org.assertj.core.api.Java6Assertions.assertThat;
8
+
9
+public class StringUtilsTest extends BaseTest {
10
+	@Test
11
+	public void isEqual() throws Exception {
12
+		assertThat(StringUtils.isEqual(null, "a")).isFalse();
13
+		assertThat(StringUtils.isEqual("a", null)).isFalse();
14
+		assertThat(StringUtils.isEqual("a", "b")).isFalse();
15
+		assertThat(StringUtils.isEqual("a", "A")).isFalse();
16
+		assertThat(StringUtils.isEqual("a", "a")).isTrue();
17
+		assertThat(StringUtils.isEqual("", "")).isTrue();
18
+	}
19
+}

+ 19
- 4
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/NavigatorTest.java View File

5
 import com.reactnativenavigation.BaseTest;
5
 import com.reactnativenavigation.BaseTest;
6
 import com.reactnativenavigation.mocks.SimpleViewController;
6
 import com.reactnativenavigation.mocks.SimpleViewController;
7
 
7
 
8
+import org.junit.Ignore;
8
 import org.junit.Test;
9
 import org.junit.Test;
9
 import org.robolectric.Shadows;
10
 import org.robolectric.Shadows;
10
 
11
 
11
-import java.util.regex.Pattern;
12
-
13
 import static org.assertj.core.api.Java6Assertions.assertThat;
12
 import static org.assertj.core.api.Java6Assertions.assertThat;
14
 
13
 
15
 public class NavigatorTest extends BaseTest {
14
 public class NavigatorTest extends BaseTest {
62
 
61
 
63
 	@Test
62
 	@Test
64
 	public void holdsUniqueId() throws Exception {
63
 	public void holdsUniqueId() throws Exception {
65
-		assertThat(uut.getId()).startsWith("navigator").matches(Pattern.compile("navigator\\d"));
64
+		assertThat(uut.getId()).startsWith("navigator");
66
 		assertThat(new Navigator(activity).getId()).isNotEqualTo(uut.getId());
65
 		assertThat(new Navigator(activity).getId()).isNotEqualTo(uut.getId());
67
 	}
66
 	}
68
 
67
 
68
+	@Test
69
+	@Ignore
70
+	public void holdsAllViewControllersById() throws Exception {
71
+		StackController stackController = new StackController(activity, "stack1");
72
+		stackController.push(child1);
73
+		stackController.push(child2);
74
+		assertThat(uut.getViewController(child1.getId())).isNull();
75
+		uut.setRoot(stackController);
76
+		assertThat(uut.getViewController(child1.getId())).isEqualTo(child1);
77
+		assertThat(uut.getViewController(child2.getId())).isEqualTo(child2);
78
+	}
79
+
80
+//	@Test
81
+//	public void push_OnTopOf() throws Exception {
82
+//		uut.push(child2, child1);
83
+//	}
84
+
69
 	private void assertHasSingleChildViewOf(ViewController vc) {
85
 	private void assertHasSingleChildViewOf(ViewController vc) {
70
 		assertThat(uut.getView().getChildCount()).isEqualTo(1);
86
 		assertThat(uut.getView().getChildCount()).isEqualTo(1);
71
 		assertThat(uut.getView().getChildAt(0)).isEqualTo(vc.getView()).isNotNull();
87
 		assertThat(uut.getView().getChildAt(0)).isEqualTo(vc.getView()).isNotNull();
72
 	}
88
 	}
73
-
74
 }
89
 }

+ 18
- 11
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/StackControllerTest.java View File

36
 
36
 
37
 	@Test
37
 	@Test
38
 	public void holdsAStackOfViewControllers() throws Exception {
38
 	public void holdsAStackOfViewControllers() throws Exception {
39
-		assertThat(uut.getStack()).isEmpty();
39
+		assertThat(uut.isEmpty()).isTrue();
40
 		uut.push(child1);
40
 		uut.push(child1);
41
 		uut.push(child2);
41
 		uut.push(child2);
42
 		uut.push(child3);
42
 		uut.push(child3);
43
-		assertThat(uut.getStack()).containsOnly(child3, child2, child1);
44
 		assertThat(uut.peek()).isEqualTo(child3);
43
 		assertThat(uut.peek()).isEqualTo(child3);
44
+		assertThat(uut.getStack()).containsOnly(child1.getId(), child2.getId(), child3.getId());
45
 	}
45
 	}
46
 
46
 
47
 	@Test
47
 	@Test
48
 	public void push() throws Exception {
48
 	public void push() throws Exception {
49
-		assertThat(uut.getStack()).isEmpty();
49
+		assertThat(uut.isEmpty()).isTrue();
50
 		uut.push(child1);
50
 		uut.push(child1);
51
-		assertThat(uut.getStack()).containsOnly(child1);
51
+		assertThat(uut.getStack()).containsOnly(child1.getId());
52
 	}
52
 	}
53
 
53
 
54
 	@Test
54
 	@Test
55
 	public void pop() throws Exception {
55
 	public void pop() throws Exception {
56
 		uut.push(child1);
56
 		uut.push(child1);
57
 		uut.push(child2);
57
 		uut.push(child2);
58
-		assertThat(uut.getStack()).containsOnly(child2, child1);
58
+		assertThat(uut.getStack()).containsOnly(child2.getId(), child1.getId());
59
 		uut.pop();
59
 		uut.pop();
60
-		assertThat(uut.getStack()).containsOnly(child1);
60
+		assertThat(uut.getStack()).containsOnly(child1.getId());
61
 	}
61
 	}
62
 
62
 
63
 	@Test
63
 	@Test
106
 
106
 
107
 		uut.push(child1);
107
 		uut.push(child1);
108
 		uut.pop();
108
 		uut.pop();
109
-		assertThat(uut.getStack()).containsOnly(child1);
109
+		assertThat(uut.getStack()).containsOnly(child1.getId());
110
 	}
110
 	}
111
 
111
 
112
 	@Test
112
 	@Test
114
 		assertThat(uut.getStack()).isEmpty();
114
 		assertThat(uut.getStack()).isEmpty();
115
 		assertThat(uut.canPop()).isFalse();
115
 		assertThat(uut.canPop()).isFalse();
116
 		uut.push(child1);
116
 		uut.push(child1);
117
-		assertThat(uut.getStack()).containsOnly(child1);
117
+		assertThat(uut.getStack()).containsOnly(child1.getId());
118
 		assertThat(uut.canPop()).isFalse();
118
 		assertThat(uut.canPop()).isFalse();
119
 		uut.push(child2);
119
 		uut.push(child2);
120
-		assertThat(uut.getStack()).containsOnly(child1, child2);
120
+		assertThat(uut.getStack()).containsOnly(child1.getId(), child2.getId());
121
 		assertThat(uut.canPop()).isTrue();
121
 		assertThat(uut.canPop()).isTrue();
122
 	}
122
 	}
123
 
123
 
159
 		uut.push(child1);
159
 		uut.push(child1);
160
 		uut.push(child2);
160
 		uut.push(child2);
161
 		uut.pop(child2);
161
 		uut.pop(child2);
162
-		assertThat(uut.getStack()).containsOnly(child1);
162
+		assertThat(uut.getStack()).containsOnly(child1.getId());
163
 		assertHasSingleChildViewOfController(child1);
163
 		assertHasSingleChildViewOfController(child1);
164
 	}
164
 	}
165
 
165
 
170
 		assertHasSingleChildViewOfController(child2);
170
 		assertHasSingleChildViewOfController(child2);
171
 
171
 
172
 		uut.pop(child1);
172
 		uut.pop(child1);
173
-		assertThat(uut.getStack()).containsOnly(child2);
173
+		assertThat(uut.getStack()).containsOnly(child2.getId());
174
 		assertHasSingleChildViewOfController(child2);
174
 		assertHasSingleChildViewOfController(child2);
175
 	}
175
 	}
176
 
176
 
225
 		assertThat(uut.isEmpty()).isTrue();
225
 		assertThat(uut.isEmpty()).isTrue();
226
 	}
226
 	}
227
 
227
 
228
+	@Test
229
+	public void holdsChildrenById() throws Exception {
230
+		assertThat(uut.getChildById(child1.getId())).isNull();
231
+		uut.push(child1);
232
+		assertThat(uut.getChildById(child1.getId())).isEqualTo(child1);
233
+	}
234
+
228
 	private void assertHasSingleChildViewOfController(ViewController childController) {
235
 	private void assertHasSingleChildViewOfController(ViewController childController) {
229
 		assertThat(uut.getView().getChildCount()).isEqualTo(1);
236
 		assertThat(uut.getView().getChildCount()).isEqualTo(1);
230
 		assertThat(uut.getView().getChildAt(0)).isEqualTo(childController.getView());
237
 		assertThat(uut.getView().getChildAt(0)).isEqualTo(childController.getView());