-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added transition handling between the side drawer and chats #2221
Added transition handling between the side drawer and chats #2221
Conversation
This should be moved to HOC though
This check is no longer needed 1. It didn't work accurately 2. The compose component is unmounted when the drawer is expanded
@marcaaron This is my rough sketch of how things can work This is a draft - Please don't pay attention to stuff that needs to be cleaned up. There are some lint errors and I'm yet to move styles, add documentation etc... There are a few items I want to ask:
So all in all I've still got some work to polish this but what do you say? |
2a68e47
to
4cf35fd
Compare
`reportID` comes with a delay when the prop comes from onyx The user first selects a route in the drawer The route immediately hides the drawer and reviews the report screen `reportID` have not yet updated and the old report is visible for a moment Switching to route params changes the `reportID` the moment the user selects one of the sidebar chat links
Don't trigger a navigation event as this causes a few unintended re-renders We don't need to trigger a navigation when can review the drawer from any chat screen we're currently on
Keep the view mounted when the report doesn't change Unmount the input when the drawer covers the view Set autoFocus only for bigger screens as example
…itching This is now handled by re-mounting Remove action sorting performed on each render - apply only when actions change
This prop no longer exists The calculation seems to be handled differently and this is leftover
This is no longer needed - functionality extracted outside
32c3c77
to
199fb11
Compare
Nicer transition on iOS. I can't see any difference on Android
…ut here This will: - remove focus / hide the keyboard when we go back to the LHN - prevent focusing on the input while it's covered by the LHN - enable the field when LHN is collapsed (or permanent)
Updated |
Thanks, totally missed the addition of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love the code changes here. Thanks!
The full page loader is slightly strange on web/desktop/larger screens, but I think we can address that in a follow up if anyone has major issues with it.
Assuming no regressions in next week @kidroca this will be paid on 15 April 👍🏽 |
@kidroca I think this is because we've switched from using the https://expensify.slack.com/archives/C01GTK53T8Q/p1617908395456000 We can either:
|
The proper fix is to address the navigation it's related to other issues like the URL changing on mWeb, but I can't do it in the scope of the current ticket. If you want me to work on that I'll need a new ticket. I can revert to using |
Here's how it would look like on Android when I revert to Android.Report.Switch.mp4This is an issue with slow AsyncStorage access speed. I don't know how exactly ONYX works, but it might be possible to add a small proxy layer that persists data but keeps in in memory as well, so when it is accessed it can come instantly and don't have to be read from the file system first. |
I leave that up to you @kidroca. It's a regression from what we had before so we must do something for now :) I agree that switching the p.s. I think maybe the video shared is to show some other behavior than what you are describing. |
Yep, sorry, updated the comment Btw I thought of another patch fix that would better address this at the moment, I'll open a new PR. Should I copy the current PR description there? |
Ah, no need, linking back to this PR should be enough. |
We found this issue that looks related to this PR #2327. Not completely sure since the issue is reproducible in production. |
if (!_.isEqual(nextProps.reportActions, this.props.reportActions)) { | ||
this.updateSortedReportActions(nextProps.reportActions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More than a year ago that this was added now, but wondering if there was any particular reason this side-effect was put in shouldComponentUpdate
instead of componentDidUpdate
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it because you were hoping to avoid having to evaluate _.isEqual(nextProps.reportAction, this.props.reportActions)
in both shouldComponentUpdate and
componentDidUpdate`?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not exactly... componentDidUpdate()
happens after the render()
so (as things are now) if we sorted the actions there then we'd also need to trigger an re-render somehow.
Using shouldComponentUpdate()
with a class property is a way to re-sort actions before the render()
method is called.
I guess a more current approach could be to recalculate the options in the render with a dependency on props.reportActions
, but my hook fu is pretty weak tbh 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More than a year ago that this was added now, but wondering if there was any particular reason this side-effect was put in
shouldComponentUpdate
instead ofcomponentDidUpdate
?
Marc already answered, but yes, to capture sortedActions
before rendering and without triggering a re-render
I guess a more current approach could be to recalculate the options in the render with a dependency on
props.reportActions
If your talking about hooks it would be as simple as
const sortedActions = useMemo(() => util.sortActions(props.reportActions), [props.reportActions])
But then the component would need to be converted from a class to a function based component (to use hooks)
For a class component the only way to sort actions, (only) when the prop changed, is to use shouldComponentUpdate
Another alternative is to subscribe the view to reportId
actions, and sort them in the connection
configuration, so the component always receives sorted actions (they'd still be sorted only if they change)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that's sort of what I had in mind. But, I think _.isEqual()
is doing an optimized deep comparison whereas useMemo()
would only run if the reportActions
failed a simple object comparison? (so even better)
Another alternative is to subscribe the view to reportId actions, and sort them in the connection configuration, so the component always receives sorted actions (they'd still be sorted only if they change)
That's pretty interesting. If we are doing a keyChanged()
then we know the subscriber is getting new data and it's an opportunity to run some logic without having to do the deep compare.
That said, I think we are maybe always creating new objects when merging or setting changes so when calling keysChanged()
the simple compare in useMemo()
might be all that we'd need. When keyChanged is called the object reference for something like props.reportActions
would be pointing to a new object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This conversation here is slightly related -> Expensify/react-native-onyx#185
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another alternative is to subscribe the view to reportId actions, and sort them in the connection configuration, so the component always receives sorted actions (they'd still be sorted only if they change)
This is pretty interesting, but I think overall the hook-based approach might be simpler/more accessible to more people in the long term?
Anyways, thanks for the thorough answers here!
@marcaaron
Details
Add a loading transition when chat is selected and the side drawer closes
withDrawerState
HOCFixed Issues
Fixes #2154 fixes #2150Tests
The keyboard should be dismissed when you go back to the LHN
QA Steps
Same as the Tests above
Tested On
Screenshots
Web
Expensify.cash.-.Google.Chrome.2021-04-08.22-20-51.mp4
Mobile Web
Screen.Recording.2021-04-08.at.22.37.58.mov
Desktop
Screen.Recording.2021-04-08.at.23.14.44.mov
iOS (Simulator)
Screen.Recording.2021-04-08.at.22.19.36.mov
Android
Android.Emulator.-.Pixel_2_API_29_5554.2021-04-08.22-10-54.mp4