Added suspense to TODO list and added interactions to 'Commit Info' panel
Brian Vaughn committed
Mar 20, 2019 at 09:39 UTC
17a966651cc1ee92ece83b71f4671133f2a830ce
8 files changed
+109
-56
package.json
+4
-3
@@ -93,13 +93,14 @@
93
"opener": "^1.5.1",
94
"prettier": "^1.16.1",
95
"prop-types": "^15.6.2",
96
- "react": "^16.8",
96
+ "react": "^16.8.4",
97
"react-color": "^2.11.7",
98
- "react-dom": "^16.8",
99
- "react-is": "^16.8",
98
+ "react-dom": "^16.8.4",
99
+ "react-is": "^16.8.4",
100
"react-portal": "^3.1.0",
101
"react-virtualized-auto-sizer": "^1.0.2",
102
"react-window": "^1.5.1",
103
+ "scheduler": "^0.13",
104
"semver": "^5.5.1",
105
"style-loader": "^0.23.1",
106
"web-ext": "^1.10.1",
shells/dev/app/ToDoList/List.js
+28
-21
@@ -1,6 +1,7 @@
1
// @flow
2
3
import React, { Fragment, useCallback, useState } from 'react';
4
+import { unstable_trace as trace } from 'scheduler/tracing';
5
import ListItem from './ListItem';
6
import styles from './List.css';
7
@@ -23,16 +24,18 @@ export default function List(props: Props) {
24
25
const handleClick = useCallback(() => {
26
if (newItemText !== '') {
26
- setItems([
27
- ...items,
28
- {
29
- id: uid,
30
- isComplete: false,
31
- text: newItemText,
32
- },
33
- ]);
34
- setUID(uid + 1);
35
- setNewItemText('');
27
+ trace(`Add "${newItemText}"`, performance.now(), () => {
28
+ setItems([
29
+ ...items,
30
+ {
31
+ id: uid,
32
+ isComplete: false,
33
+ text: newItemText,
34
+ },
35
+ ]);
36
+ setUID(uid + 1);
37
+ setNewItemText('');
38
+ });
39
}
40
}, [newItemText, items, uid]);
41
@@ -54,24 +57,28 @@ export default function List(props: Props) {
57
58
const removeItem = useCallback(
59
itemToRemove => {
57
- setItems(items.filter(item => item !== itemToRemove));
60
+ trace(`Remove "${itemToRemove.text}"`, performance.now(), () => {
61
+ setItems(items.filter(item => item !== itemToRemove));
62
+ });
63
},
64
[items]
65
);
66
67
const toggleItem = useCallback(
68
itemToToggle => {
64
- const index = items.indexOf(itemToToggle);
69
+ trace(`Toggle "${itemToToggle.text}"`, performance.now(), () => {
70
+ const index = items.indexOf(itemToToggle);
71
66
- setItems(
67
- items
68
- .slice(0, index)
69
- .concat({
70
- ...itemToToggle,
71
- isComplete: !itemToToggle.isComplete,
72
- })
73
- .concat(items.slice(index + 1))
74
- );
72
+ setItems(
73
+ items
74
+ .slice(0, index)
75
+ .concat({
76
+ ...itemToToggle,
77
+ isComplete: !itemToToggle.isComplete,
78
+ })
79
+ .concat(items.slice(index + 1))
80
+ );
81
+ });
82
},
83
[items]
84
);
shells/dev/app/ToDoList/ListItem.js
+4
-2
@@ -1,6 +1,6 @@
1
// @flow
2
3
-import React, { useCallback } from 'react';
3
+import React, { memo, useCallback } from 'react';
4
import styles from './ListItem.css';
5
6
import type { Item } from './List';
@@ -11,7 +11,7 @@ type Props = {|
11
toggleItem: (item: Item) => void,
12
|};
13
14
-export default function ListItem({ item, removeItem, toggleItem }: Props) {
14
+function ListItem({ item, removeItem, toggleItem }: Props) {
15
const handleDelete = useCallback(() => {
16
removeItem(item);
17
}, [item, removeItem]);
@@ -37,3 +37,5 @@ export default function ListItem({ item, removeItem, toggleItem }: Props) {
37
</li>
38
);
39
}
40
+
41
+export default memo<Props>(ListItem);
src/devtools/cache.js
+18
-3
@@ -1,6 +1,6 @@
1
// @flow
2
3
-import { createContext, useContext } from 'react';
3
+import React, { createContext } from 'react';
4
5
// Cache implementation was forked from the React repo:
6
// https://github.com/facebook/react/blob/master/packages/react-cache/src/ReactCache.js
@@ -46,6 +46,21 @@ const Pending = 0;
46
const Resolved = 1;
47
const Rejected = 2;
48
49
+const ReactCurrentDispatcher = (React: any)
50
+ .__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher;
51
+
52
+function readContext(Context, observedBits) {
53
+ const dispatcher = ReactCurrentDispatcher.current;
54
+ if (dispatcher === null) {
55
+ throw new Error(
56
+ 'react-cache: read and preload may only be called from within a ' +
57
+ "component's render. They are not supported in event handlers or " +
58
+ 'lifecycle methods.'
59
+ );
60
+ }
61
+ return dispatcher.readContext(Context, observedBits);
62
+}
63
+
64
function identityHashFn(input) {
65
return input;
66
}
@@ -106,7 +121,7 @@ export function createResource<I, K: string | number, V>(
121
read(input: I): V {
122
// Prevent access outside of render.
123
// eslint-disable-next-line react-hooks/rules-of-hooks
109
- useContext(CacheContext);
124
+ readContext(CacheContext);
125
126
const key = hashInput(input);
127
const result: Result<V> = accessResult(resource, fetch, input, key);
@@ -132,7 +147,7 @@ export function createResource<I, K: string | number, V>(
147
preload(input: I): void {
148
// Prevent access outside of render.
149
// eslint-disable-next-line react-hooks/rules-of-hooks
135
- useContext(CacheContext);
150
+ readContext(CacheContext);
151
152
const key = hashInput(input);
153
accessResult(resource, fetch, input, key);
src/devtools/views/Profiler/SidebarCommitInfo.css
+9
-3
@@ -12,14 +12,20 @@
12
padding: 0.5rem;
13
}
14
15
-.List {
15
+.List,
16
+.InteractionList {
17
list-style: none;
18
margin: 0;
19
padding: 0;
20
}
21
21
-.ListItem {
22
- margin: 0 0 0.25rem;
22
+.InteractionList {
23
+ padding: 0.5rem;
24
+}
25
+
26
+.ListItem,
27
+.InteractionListItem {
28
+ margin: 0 0 0.5rem;
29
}
30
31
.Label {
src/devtools/views/Profiler/SidebarCommitInfo.js
+24
-9
@@ -15,6 +15,11 @@ export default function SidebarCommitInfo(_: Props) {
15
);
16
17
const { profilingCache } = useContext(StoreContext);
18
+
19
+ if (selectedCommitIndex === null) {
20
+ return null; // TODO (profiling) Use a better UI
21
+ }
22
+
23
const { commitDurations, commitTimes } = profilingCache.ProfilingSummary.read(
24
{
25
rendererID: ((rendererID: any): number),
@@ -22,9 +27,11 @@ export default function SidebarCommitInfo(_: Props) {
27
}
28
);
29
25
- if (selectedCommitIndex === null) {
26
- return 'TODO';
27
- }
30
+ const { interactions } = profilingCache.CommitDetails.read({
31
+ commitIndex: ((selectedCommitIndex: any): number),
32
+ rendererID: ((rendererID: any): number),
33
+ rootID: ((rootID: any): number),
34
+ });
35
36
return (
37
<Fragment>
@@ -34,21 +41,29 @@ export default function SidebarCommitInfo(_: Props) {
41
<li className={styles.ListItem}>
42
<label className={styles.Label}>Committed at</label>:{' '}
43
<span className={styles.Value}>
37
- {formatTime(commitTimes[selectedCommitIndex])}s
44
+ {formatTime(commitTimes[((selectedCommitIndex: any): number)])}s
45
</span>
46
</li>
47
<li className={styles.ListItem}>
48
<label className={styles.Label}>Render duration</label>:{' '}
49
<span className={styles.Value}>
43
- {formatDuration(commitDurations[selectedCommitIndex])}ms
50
+ {formatDuration(
51
+ commitDurations[((selectedCommitIndex: any): number)]
52
+ )}
53
+ ms
54
</span>
55
</li>
56
<li className={styles.ListItem}>
57
<label className={styles.Label}>Interactions</label>:
48
- <ul className={styles.List}>
49
- <li className={styles.ListItem}>
50
- <div>Coming soon</div>
51
- </li>
58
+ <ul className={styles.InteractionList}>
59
+ {interactions.length === 0 ? (
60
+ <li className={styles.InteractionListItem}>None</li>
61
+ ) : null}
62
+ {interactions.map((interaction, index) => (
63
+ <li key={index} className={styles.ListItem}>
64
+ {interaction.name}
65
+ </li>
66
+ ))}
67
</ul>
68
</li>
69
</ul>
src/devtools/views/Profiler/SnapshotSelector.js
+2
@@ -12,6 +12,8 @@ import styles from './SnapshotSelector.css';
12
13
export type Props = {||};
14
15
+// TODO (profiling) Left/right arrow navigation.
16
+
17
export default function SnapshotSelector(_: Props) {
18
const {
19
isCommitFilterEnabled,
yarn.lock
+20
-15
@@ -8630,21 +8630,26 @@ react-color@^2.11.7:
8630
reactcss "^1.2.0"
8631
tinycolor2 "^1.4.1"
8632
8633
-react-dom@^16.8:
8634
- version "16.8.3"
8635
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.3.tgz#ae236029e66210783ac81999d3015dfc475b9c32"
8636
- integrity sha512-ttMem9yJL4/lpItZAQ2NTFAbV7frotHk5DZEHXUOws2rMmrsvh1Na7ThGT0dTzUIl6pqTOi5tYREfL8AEna3lA==
8633
+react-dom@^16.8.4:
8634
+ version "16.8.4"
8635
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.4.tgz#1061a8e01a2b3b0c8160037441c3bf00a0e3bc48"
8636
+ integrity sha512-Ob2wK7XG2tUDt7ps7LtLzGYYB6DXMCLj0G5fO6WeEICtT4/HdpOi7W/xLzZnR6RCG1tYza60nMdqtxzA8FaPJQ==
8637
dependencies:
8638
loose-envify "^1.1.0"
8639
object-assign "^4.1.1"
8640
prop-types "^15.6.2"
8641
- scheduler "^0.13.3"
8641
+ scheduler "^0.13.4"
8642
8643
-react-is@^16.8, react-is@^16.8.1:
8643
+react-is@^16.8.1:
8644
version "16.8.3"
8645
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.3.tgz#4ad8b029c2a718fc0cfc746c8d4e1b7221e5387d"
8646
integrity sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA==
8647
8648
+react-is@^16.8.4:
8649
+ version "16.8.4"
8650
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2"
8651
+ integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==
8652
+
8653
react-portal@^3.1.0:
8654
version "3.2.0"
8655
resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-3.2.0.tgz#4224e19b2b05d5cbe730a7ba0e34ec7585de0043"
@@ -8665,15 +8670,15 @@ react-window@^1.5.1:
8670
"@babel/runtime" "^7.0.0"
8671
memoize-one "^3.1.1"
8672
8668
-react@^16.8:
8669
- version "16.8.3"
8670
- resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9"
8671
- integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA==
8673
+react@^16.8.4:
8674
+ version "16.8.4"
8675
+ resolved "https://registry.yarnpkg.com/react/-/react-16.8.4.tgz#fdf7bd9ae53f03a9c4cd1a371432c206be1c4768"
8676
+ integrity sha512-0GQ6gFXfUH7aZcjGVymlPOASTuSjlQL4ZtVC5YKH+3JL6bBLCVO21DknzmaPlI90LN253ojj02nsapy+j7wIjg==
8677
dependencies:
8678
loose-envify "^1.1.0"
8679
object-assign "^4.1.1"
8680
prop-types "^15.6.2"
8676
- scheduler "^0.13.3"
8681
+ scheduler "^0.13.4"
8682
8683
reactcss@^1.2.0:
8684
version "1.2.3"
@@ -9279,10 +9284,10 @@ sax@>=0.6.0, sax@^1.2.4:
9284
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
9285
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
9286
9282
-scheduler@^0.13.3:
9283
- version "0.13.3"
9284
- resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.3.tgz#bed3c5850f62ea9c716a4d781f9daeb9b2a58896"
9285
- integrity sha512-UxN5QRYWtpR1egNWzJcVLk8jlegxAugswQc984lD3kU7NuobsO37/sRfbpTdBjtnD5TBNFA2Q2oLV5+UmPSmEQ==
9287
+scheduler@^0.13, scheduler@^0.13.4:
9288
+ version "0.13.4"
9289
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.4.tgz#8fef05e7a3580c76c0364d2df5e550e4c9140298"
9290
+ integrity sha512-cvSOlRPxOHs5dAhP9yiS/6IDmVAVxmk33f0CtTJRkmUWcb1Us+t7b1wqdzoC0REw2muC9V5f1L/w5R5uKGaepA==
9291
dependencies:
9292
loose-envify "^1.1.0"
9293
object-assign "^4.1.1"