Expensify / App

Welcome to New Expensify: a complete re-imagination of financial collaboration, centered around chat. Help us build the next generation of Expensify by sharing feedback and contributing to the code.
https://new.expensify.com
MIT License
3.46k stars 2.81k forks source link

[Ideal Nav] [$1000] [Tracking] Update navigation to support wide layouts on native #35854

Open roryabraham opened 8 months ago

roryabraham commented 8 months ago

Slack context: https://expensify.slack.com/archives/C07J32337/p1707147391183469

Problem

We have an iPad app, and it doesn't work as expected, because we have code that assumes that any code in index.native.js must be representing a narrow layout. Using platform as a proxy for:

is a bad practice and a source for technical debt. It also violates one of the driving philosophies of this app - cross platform 99.99%.

For the sake of scope management, this issue will focus on removing instances where platform is used as a proxy for device layout, specifically these known issues, which will soon be fixed via a temporary workaround.

Solution

Remove code in index.native.js files that assumes it will be running on a narrow layout. Let's get wide layouts working on an iPad Pro (in portrait mode). When this was investigated before, one of the key difficulties found was that we rely on position: fixed in wide layouts on web, but that style is not currently supported in React Native.

This does not mean we will allow the native apps to rotate into a landscape mode.

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01290d6331a572c985
  • Upwork Job ID: 1754814923483574272
  • Last Price Increase: 2024-08-08
roryabraham commented 8 months ago

cc @mountiny @hayata-suenaga @adamgrzybowski @WojtekBoman @mateuuszzzzz @kosmydel @MaciejSWM

roryabraham commented 8 months ago

Maybe one alternative to using position: fixed would be to leverage @gorhom/portal to move the view outside the positional scope, as suggested here

hayata-suenaga commented 8 months ago

What if we create a parent component that fills the entire screen with its position set to relative, and then make the target component a child of this parent component, setting its position to absolute?

melvin-bot[bot] commented 8 months ago

Job added to Upwork: https://www.upwork.com/jobs/~01290d6331a572c985

melvin-bot[bot] commented 8 months ago

Triggered auto assignment to Contributor-plus team member for initial proposal review - @sobitneupane (External)

melvin-bot[bot] commented 8 months ago

Triggered auto assignment to @sakluger (NewFeature), see https://stackoverflowteams.com/c/expensify/questions/14418#:~:text=BugZero%20process%20steps%20for%20feature%20requests for more details.

mountiny commented 8 months ago

Noted in the OP we still do not want to allow the landscape mode. Making this External to get proposals going. If anything is not clear, please ask. Thanks

hayata-suenaga commented 8 months ago

Can I close my issue Unable to navigate away from Profile page using the back button (which is already linked on the OP) as the issue will be fixed in this issue?

mountiny commented 8 months ago

@hayata-suenaga that issue is linked to the PR so I would just leave it open so we can confirm it was fixed in staging once the PR is deployed

roryabraham commented 8 months ago

From Nick Gerleman at Meta:

We actually just spent a couple months adding support for position: "static" in the new architecture.

I will warn that adding position: "fixed" would be fairly complicated, and break a good number of assumptions in both Yoga and Fabric. E.g. beyond layout, it we would need to change Fabric mounting layer as well (e.g. we couldn't put a fixed item under a scrolling container. IIRC fixed has stacking context implications as well).

I would discourage trying to take it on without previous experience in both Yoga and Fabric's mounting later.

roryabraham commented 8 months ago

It sounds like that would be a potentially valuable improvement, but we'd need to assemble a dream team to do it and recognize that it would be a big initiative that would take a lot of time and might not be a top priority for Meta.

An alternate solution, if possible, would be much more expedient.

adamgrzybowski commented 8 months ago

The position fixed is used because we need to modify the position of cards inside the StackView component provided by react-navigation, to display them side by side.

As a potential idea to investigate, we could try to use two or more StackViews in the custom navigator. This should give us more flexibility with positioning.

Alternatively, we could create our own / modify the StackView.

However, I am not sure how it would work with native stacks

melvin-bot[bot] commented 8 months ago

πŸ“£ It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? πŸ’Έ

melvin-bot[bot] commented 7 months ago

Upwork job price has been updated to $1000

mountiny commented 7 months ago

Bumping this to hopefully get some proposals here

melvin-bot[bot] commented 7 months ago

πŸ“£ It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? πŸ’Έ

sakluger commented 7 months ago

Posted in the Callstack Slack room to ask for volunteers.

rezkiy37 commented 7 months ago

Hi, I’m Michael (Mykhailo) from Callstack and I would like to work on this issue.

badeggg commented 7 months ago

Does this issue still need proposal?

rezkiy37 commented 7 months ago

I am already working to prepare a proposal.

rezkiy37 commented 7 months ago

Actively working on the issue. Resolving a problem with 2 active stacks on a screen at the same moment.

rezkiy37 commented 7 months ago

Still trying to implement 2 active stacks on a screen at the same moment.

rezkiy37 commented 7 months ago

Discuss internally how to handle the feature with 2 active stacks on a screen at the same moment.

rezkiy37 commented 7 months ago

I need to create a custom navigator to handle this case on native devices (iPads). So, I am going to develop it. Btw, looks like it is a hard task, therefore I need some time to investigate and implement.

trjExpensify commented 7 months ago

πŸ‘‹ can someone catch me up on why this one was added to #wave8, and should it now be transfered to #wave-collect?

rezkiy37 commented 7 months ago

Going to integrate something similar to what they described in this article. Testing on a bare project now.

mountiny commented 7 months ago

@rezkiy37 Just wanted point you also towards this ideal nav PR which makes some updates to the navigators https://github.com/Expensify/App/pull/37421

@trjExpensify This is a follow up to the ideal nav / app navigation reboot updates, we want to clean up how the layout is handled based on the device size.

At the moment, some actions are decided based on the screen width which because on native devices we struggled to achieve the desktop layout due to some RN styling limitations. We want to remove this debt.

It was added as a follow up to ideal nav then

trjExpensify commented 7 months ago

Okay, so @mountiny I'm putting this one in #wave-collect polish. I've also added [Ideal Nav] in the issue title to associate it with that project.

mountiny commented 7 months ago

Thank you!

rezkiy37 commented 7 months ago

I have some progress on the issue. The idea is to have 2 NavigationContainers. Continue working on it.

Screenshot 2024-03-12 at 18 47 22 Screenshot 2024-03-12 at 18 47 27
rezkiy37 commented 6 months ago

Hey! I must inform you that I have a vacation next week. I will be back on Monday 25.03. During the vacation, someone from Callstack can take the issue to work. See you soon!

trjExpensify commented 6 months ago

Welcome back, @rezkiy37! Will you be able to finish this off this week?

rezkiy37 commented 6 months ago

Hello! Yeah, I am going to work on the issue actively. Also, I have the high-priority Invoicing V1 feature. I will post daily updates so will see. Thank you!

rezkiy37 commented 6 months ago

I have some progress today. The app has started to render 2 stacks. Also, I was able to integrate a draft communication between them.

https://github.com/Expensify/App/assets/57314631/43a33c5c-2a6e-4a58-ba53-70a65394ae12

https://github.com/Expensify/App/assets/57314631/7432c3bb-5114-4a62-8a65-ec5c6b0741c9

mountiny commented 6 months ago

Nice thank you for the update

mountiny commented 6 months ago

Noting here to also clean this up in this issue https://github.com/Expensify/App/pull/37733#discussion_r1549674935 once we have standardized way to handle the layouts

rezkiy37 commented 6 months ago

Another high-priority task occupied me. I am going to focus on this one tomorrow.

rezkiy37 commented 6 months ago

Updates: I was working on a behavior to persist previous pages for the tabs. The app remembers a chat and settings pages to get the proper previous page to open via the tabs. Also, I was able to configure the workspace settings page. The next goal is to configure all modal stacks to be workable.

https://github.com/Expensify/App/assets/57314631/205a2da1-0f0f-49c7-b7dd-6a6fdc13e50e

rezkiy37 commented 6 months ago

Updates: I've configured the modal stacks to open and work with them. The next goal is to have the overlay effect.

https://github.com/Expensify/App/assets/57314631/c465b9f2-c943-46a1-9941-90f9781c7e6f

rezkiy37 commented 6 months ago

I am stopping working on the issue as it was discussed in Slack. So I am leaving all my investigation in this comment.

I have a draft PR with a raw implementation. Unfortunately, I didn't find a solution to integrate 2 navigators to work in parallel within one NavigationContainer. The main idea was to create an independent NavigationContainer for the left side of a screen (bottom tab navigator). It allows us to place them near each other. Also, I needed to create one more navigation handler because the bottom tab navigator is no longer part of the RootStack.

Useful link: https://dev.to/retyui/how-to-implement-split-view-on-a-tablet-with-react-native-167e.

I pushed all changes to the PR. Feel free to ask any question πŸ™‚

mountiny commented 5 months ago

Assigning @allroundexperts who would like to work on this one on the backburner! I have proposed a price of $4000 for total completion of this project with clean up tasks merged too/ any regressions found staging too.

allroundexperts commented 5 months ago

As next steps, I'll be taking a first peek at this tomorrow. I think I have a different way in my mind than the draft PR, but will experiment with it tomorrow.

mountiny commented 5 months ago

Ok, thanks, please keep us updated here, I would prefer to not to spend too much time in the design phase here, unless you have some clear reasons why the current approach in the PR from @rezkiy37 is wrong

mountiny commented 5 months ago

@allroundexperts What is the latest? I think you are working on some other projects too, would you like to hand this one off to someone else?

allroundexperts commented 5 months ago

I'd be occupied with a bug on actionable whisper this week. If this is urgent, please re-assign.

mountiny commented 5 months ago

Asked in C+ channel for new volunteeer

mountiny commented 5 months ago

Discussed in Slack @mananjadhav will take over. Can you please make a steady progress on this with frequent updates? Feel free to ask Michael for any help too

mananjadhav commented 5 months ago

I'll check this over the weekend and start with this Monday.

mananjadhav commented 5 months ago

I went through the history of the issue and now going through the linked PR. I couldn't find a straight forward way (obviously) to have two navigators in the single NavigationContainer. I am still exploring this as a possibility.

The main idea was to create an independent NavigationContainer for the left side of a screen (bottom tab navigator).

@rezkiy37 Any specific reason we're pushing towards creating an independent NavigationContainer for the LHS? I also saw most screencasts are on iPad. Did your solution work seamlessly in the mobile devices? Is your PR a good starting point to pick this from?

I'll be posting updates every alternate day on this one.

rezkiy37 commented 5 months ago

@rezkiy37 Any specific reason we're pushing towards creating an independent NavigationContainer for the LHS?

@mananjadhav, after my investigations, I started to consider this approach as a main one. As I understand, there is no way how to render 2 pages (the LHN and central panel) on a screen for native devices. This article can help you as well.

I also saw most screencasts are on iPad. Did your solution work seamlessly in the mobile devices?

I integrated a common logic for all native devices and the web in the PR. It should work properly on Android, but I tested only on iPads.

Is your PR a good starting point to pick this from?

If you don't find any new workable approach, yes it is. Since we have 2 independent containers, we need to integrate communication between them. Also, it would be great to use the Navigation.navigate() for both containers, so it requires combining (union) inside the method.