-
Notifications
You must be signed in to change notification settings - Fork 149
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
fix: use location.state to store background route to prevent unmount #4062
Conversation
@@ -47,7 +52,13 @@ function HomeContainer({ account }: HomeContainerProps) { | |||
actions={<HomeActions />} | |||
> | |||
<HomeTabs> | |||
<Outlet context={{ address: account.address }} /> | |||
<> |
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.
I need to declare Routes
here so I can manipulate the location
depending on whether backgroundLocation
is populated or not.
backgroundLocation
is the route above which the modal should appear.
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.
Isn't it possible to also read location in app-routes to see if bg location is defined? Nw if not, just curious
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.
We can read the location there but the issue I struggled with is how to then feed said location into how we are creating the routes.
We are using createHashRouter
and createRoutesFromElements
and I was unable to figure out how to pass the location
there.
Eventually I came up with the idea of using <Routes
nested in <Home
so I could then trick the location
.
We can probably improve on that structure with more time and I am open to suggestions but I didn't want to start refactoring the whole of app-routes
716b35a
to
ca60339
Compare
ca60339
to
498742b
Compare
src/app/routes/app-routes.tsx
Outdated
@@ -186,8 +185,9 @@ function useAppRoutes() { | |||
</AccountGate> | |||
} | |||
> | |||
<Route index element={<BalancesList />} /> | |||
<Route path={RouteUrls.Activity} element={<ActivityList />} /> | |||
<Route path={RouteUrls.Activity} element={<ActivityList />}> |
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.
ActivityList
is loaded in home.tsx
but the route needs to be declared here also.
Similarly settingsModalRoutes
needs to be passed in so you can use the settings modals from /activities
@@ -47,7 +52,13 @@ function HomeContainer({ account }: HomeContainerProps) { | |||
actions={<HomeActions />} | |||
> | |||
<HomeTabs> | |||
<Outlet context={{ address: account.address }} /> | |||
<> |
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.
Isn't it possible to also read location in app-routes to see if bg location is defined? Nw if not, just curious
498742b
to
a78237a
Compare
f31f274
to
5f39481
Compare
5f39481
to
d0b9454
Compare
…using modals, closes #4028
d0b9454
to
c269825
Compare
…undLocation as home
@@ -0,0 +1,34 @@ | |||
import { useEffect } from 'react'; |
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.
I added this hook so that:
- If you have a modal open
- Open a new tab
- It will update the
backgroundLocation
to be the home page
Kapture.2023-07-28.at.14.28.19.mp4
Without doing this, an empty screen appears behind the modal
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.
Thinking on this further: couldn't each modal component handle their own backgroundLocation
logic?
Where the sign out modal component has a check in its render that, if there's no backgroundLocation
, it should re-router to having a default value of home?
Could work with a similar hook API, but where all the logic is colocated to the modal itself, rather than one big catch-all.
Something like:
// src/app/pages/sign-out-confirm/sign-out-confirm.tsx
useDefaultBackgroundLocation(RouteUrls.Home)
which internally handles the
if (!backgroundLocation) navigate(currentRoute, {
state: {
backgroundLocation: defaultVal,
// this might fix the problem you've commented in the other file re route state
...otherRouteState
}
})`
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.
Yes we can definitely do that. I just implemented a catch all for now as Home
seems like the logical background. I can change it to accept a preferred default route
I can give it a try but I think once you open a new tab the location.state
gets wiped completely.
switch (true) { | ||
// FIXME ReceiveCollectibleOrdinal loses state?.btcAddressTaproot in a new tab | ||
// this can be improved to try and fetch btcAddressTaproot | ||
case pathname === RouteUrls.ReceiveCollectibleOrdinal && !state?.btcAddressTaproot: |
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.
For RouteUrls.ReceiveCollectibleOrdinal
, it relies on btcAddressTaproot
that is set in location.state
.
If you open a new tab this state is lost and although the modal opens, the btcAddressTaproot
is lost so it's unusable.
For now I just send users back to RouteUrls.Home
. This could probably be improved by refactoring how we get btcAddressTaproot
in ReceiveCollectibleOrdinal
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 a big fan of using a switch(true)
. Why not just use if
s?
This is better for readability imo. My thoughts map to the first comment of the HN post of a guy who wrote an article doing this (https://news.ycombinator.com/item?id=26777090) re favouring early return.
Separately—while identical behaviour of modals when doing a fresh load of the app would be ideal—if we need to add a lot of logic to handle this, then I wouldn't consider it a dealbreaker if the under layer doesn't load correctly. Contextually, in case of sign out, it isn't so important.
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.
I like using switch(true)
as I think its cleaner and more elegant than a lot of if
statements. I can change it though and use early returns here and in future to match the code base.
If we are OK with having an empty screen behind all modals opened in a new tab then we can avoid the addition of this logic.
It will look like this, with home tabs but no tab content:
For RouteUrls.ReceiveCollectibleOrdinal
we will need to do something though as we lose track of the taproot address when opening in a new tab and the modal shows but is non-functional as there is no address to copy:
This PR is working and I tested it a lot but it would be good to give it a thorough look. It still throws a warning in the console due to how I have had to use I did some more work refactoring The stumbling block is that we need to use |
switch (true) { | ||
// FIXME ReceiveCollectibleOrdinal loses state?.btcAddressTaproot in a new tab | ||
// this can be improved to try and fetch btcAddressTaproot | ||
case pathname === RouteUrls.ReceiveCollectibleOrdinal && !state?.btcAddressTaproot: |
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 a big fan of using a switch(true)
. Why not just use if
s?
This is better for readability imo. My thoughts map to the first comment of the HN post of a guy who wrote an article doing this (https://news.ycombinator.com/item?id=26777090) re favouring early return.
Separately—while identical behaviour of modals when doing a fresh load of the app would be ideal—if we need to add a lot of logic to handle this, then I wouldn't consider it a dealbreaker if the under layer doesn't load correctly. Contextually, in case of sign out, it isn't so important.
export function useLocationState(propName: 'accountIndex'): number; | ||
export function useLocationState(propName: 'backgroundLocation'): Location; |
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.
These changes mean useLocationState
is now aware of implementation details of some of the cases in which it's used.
Why not extend the function to support a generic type argument, rather than extending it with use-case specific typings?
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.
I can change this, no problem. I struggled with extending the type initially so opted for this to narrow the type to their key. I'll clean it up
…d routes which are needed for modal
Closing this in favour of : #4099 |
This PR makes a change to how we handle modals displayed over routes.
location.state
is used to store the background route to prevent it being unmounted by feeding that to the router if available