We prevent user from i.g. changing thread when we are in edit mode.
Details
Run the app on iOS and Android:
- checked if we can't navigate when we are in edit mode,
- checked if we can navigate after leaving exit mode.
Diff Detail
- Repository
- rCOMM Comm
- Branch
- kuba/blocking-navigation
- Lint
No Lint Coverage - Unit
No Test Coverage
Event Timeline
Address review & fix issue with nested threads (unblocking the navigation didn't work correctly)
native/navigation/nav-selectors.js | ||
---|---|---|
334 ↗ | (On Diff #27920) | I tried doing that, but Flow blocks it: const removeEditMode: RemoveEditMode = messageListRoute.params.removeEditMode; Cannot assign `messageListRoute.params.removeEditMode` to `removeEditMode` because mixed [1] is incompatible with `RemoveEditMode` [2].Flow(incompatible-type) This is the only workaround I've found. |
Overall, looks ok, but I have a couple of questions.
native/chat/chat-input-bar.react.js | ||
---|---|---|
414 ↗ | (On Diff #28042) | For me it feels a little more natural to have previous state check on the left hand side - we're used to reading left to right |
754–756 ↗ | (On Diff #28042) | Why do we early exit here? |
905 ↗ | (On Diff #28042) | Is it a good idea to store a function in navigation? |
native/chat/chat-router.js | ||
137 ↗ | (On Diff #28042) | Why do we need this condition? |
140 ↗ | (On Diff #28042) | This is a potential bug, really hard to debug. Not sure how it works for navigation, but for redux, dispatching an action from a reducer causes some state updates to get lost. In this case it should be probably fine, as we're returning lastState (why?). But we should be really careful about it and verify this thoroughly. |
native/navigation/nav-selectors.js | ||
334 ↗ | (On Diff #27920) | Maybe we should somehow verify that messageListRoute is of correct type and its params are MessageListParams? |
address review
native/chat/chat-input-bar.react.js | ||
---|---|---|
754–756 ↗ | (On Diff #28042) | Otherwise, the user would lose his draft when he navigates away and discards his edit changes. |
905 ↗ | (On Diff #28042) | It was suggested here.
|
native/chat/chat-router.js | ||
137 ↗ | (On Diff #28042) | Here, it only applies to adding screens to the stack. Removing screens from the stack is already handled by the beforeRemove event. |
140 ↗ | (On Diff #28042) | We are returning lastState to prevent the navigation (docs). |
native/chat/chat-input-bar.react.js | ||
---|---|---|
889–892 ↗ | (On Diff #28138) | We return here true because we want to dispatch this action immediately. In that way, we don't need to dispatch the action here, because it is handled by the router. |
native/chat/chat-router.js | ||
140 ↗ | (On Diff #28042) | Great catch. It wasn't safe. In the updated version, there is a slightly different approach, which addresses this issue. |
native/chat/chat-input-bar.react.js | ||
---|---|---|
883–884 ↗ | (On Diff #28138) | Wondering how maintainable this boolean return is. From a caller's point of view, it isn't obvious what this value mean. We can address that by changing function name to something more explicit, or by changing return value to e.g. 'ignore_action' | 'reduce_action'. What do you think? |
This diff is doing a lot of things, and could probably be decomposed in four different diffs. At this point we don't have time for that unfortunately.
I am not really sure that the changes are both complete and necessary, so I will have to rely on your test plan. Can you extend the Test Plan to mention the various different things you tested to conclude each change was necessary?
native/chat/chat-input-bar.react.js | ||
---|---|---|
877 ↗ | (On Diff #28138) | Why don't we do anything if the route isn't focused? |
883–884 ↗ | (On Diff #28138) | I agree |
897 ↗ | (On Diff #28138) | The definition of this function introduces an unnecessary function alias. Can you please remove the unnecessary alias using this patch? diff --git a/native/utils/edit-messages-utils.js b/native/utils/edit-messages-utils.js index c85f888bb..dc066b031 100644 --- a/native/utils/edit-messages-utils.js +++ b/native/utils/edit-messages-utils.js @@ -14,9 +14,7 @@ function exitEditAlert(onDiscard: () => void): void { { text: 'Discard edit', style: 'destructive', - onPress: () => { - onDiscard(); - }, + onPress: onDiscard, }, ], ); |
1359 ↗ | (On Diff #28138) |
Can you try to confirm if a change in isFocused triggers a rerender, and if not can you try pass the isFocused function in directly? |
native/chat/chat-router.js | ||
137 ↗ | (On Diff #28138) | Why are we only blocking forward navigation, and not blocking backwards navigation? |
native/chat/chat-router.js | ||
---|---|---|
137 ↗ | (On Diff #28138) | Ah, I guess it's handled with the beforeRemove event. Can you add a code comment explaining that? Alternately, it might more simple to use the same mechanism for blocking all navigation, instead of splitting into two codepaths. |
native/chat/chat-input-bar.react.js | ||
---|---|---|
1359 ↗ | (On Diff #28138) | We can also consider using useFocusEffect but that might be impossible as most of the component is written using a class |
native/chat/chat-input-bar.react.js | ||
---|---|---|
1359 ↗ | (On Diff #28138) | My testing seems to confirm that every time focus change a component is rerendered. But The warning won't be there if that was guaranteed, so it's safer to avoid relying on this. Passing isFocused function is harder, as we're now checking not if a screen is currently focused, but also if it was focused previously. Still, if a rerender isn't guaranteed, passing this function won't change anything, as we need componentDidUpdate to be called. |
native/chat/chat-input-bar.react.js | ||
---|---|---|
877 ↗ | (On Diff #28138) | I must have added it when I was adding it to the blockNavigation function. It is unnecessary here because we don't block the navigation when we are not focused. I have removed it. |
native/chat/chat-input-bar.react.js | ||
---|---|---|
1359 ↗ | (On Diff #28138) | Not sure if this is the correct approach: I added listeners for blur and focus events (docs) and moved the logic to them. |
native/chat/chat-router.js | ||
137 ↗ | (On Diff #28138) | I have a quick try to remove the beforeRemove listener and block it here. Simply changing that causes an infinite loop of alerts (pressing any button on the alert opens the new one). I will add a comment. |
Great work – I think this solution looks almost perfect! Can you make sure to address the inline comments before landing? If there's any ambiguity, or if my suggestion doesn't work for some reason, please feel free to re-request review
native/chat/chat-input-bar.react.js | ||
---|---|---|
198–199 ↗ | (On Diff #28346) | Might be nice to order these in the same order as the invocations below (with the new ones below the old one) |
911–912 ↗ | (On Diff #28346) | This change will allow us to get rid of the isFocused prop. We're only doing spot checks here, so we don't need it |
1382 ↗ | (On Diff #28346) | We don't need this prop anymore, and I'm skeptical that it can be relied on anyways. Can you remove it? |
native/chat/chat-router.js | ||
137 ↗ | (On Diff #28138) | Thanks for explaining! |
native/chat/chat-input-bar.react.js | ||
---|---|---|
910 ↗ | (On Diff #28391) | Nit: shorthand |
native/chat/chat-input-bar.react.js | ||
---|---|---|
347 ↗ | (On Diff #28432) | We can early exit when !navigation. By doing that we should be able to avoid invariants |