Open roryabraham opened 10 months ago
Job added to Upwork: https://www.upwork.com/jobs/~01f36dcb081cdf74b2
Triggered auto assignment to @maddylewis (NewFeature
), see https://stackoverflowteams.com/c/expensify/questions/14418#:~:text=BugZero%20process%20steps%20for%20feature%20requests for more details.
Triggered auto assignment to Contributor-plus team member for initial proposal review - @getusha (External
)
I can work on this if no one is assigned yet, or should I write proposal
Since it is a new feature main idea is explained well in description, and I think anything else could be discussed in the PR
Create a useResponsiveLayout hook
This is a new functionality
First, we need open RHP modals navigator
And add new route option isInRHP
in screenOptions
Then we need to create a new hook For example, using the suggested option
And then we need to find isSmallScreenWidth
values
Remove those values and use shouldUseNarrowLayout
from the new hook
And at the last, we need to introduce a new lint rule that disallow using isSmallScreenWidth from useWindowDimensions
We can write a new rule
module.exports = {
meta: {
type: 'problem',
docs: {
description: 'Do not use isSmallScreenWidth from useWindowDimensions. Instead of that use shouldUseNarrowLayout from useResponsiveLayout',
category: 'Best Practices',
},
},
create: function (context) {
return {
VariableDeclarator(node) {
if ( node.init.callee && node.init.callee.name === 'useWindowDimensions') {
const properties = node.id.properties;
for (const property of properties) {
if (property.key.name === 'isSmallScreenWidth') {
context.report({
node,
message: 'Do not use isSmallScreenWidth from useWindowDimensions. Instead of that use shouldUseNarrowLayout from useResponsiveLayout',
});
}
}
}
},
};
},
};
NA
The problem we aim to address is the lack of a consistent and reliable method to determine the appropriate layout for mobile devices and wide screens within our application. Currently, we rely on the isSmallScreenWidth
property from the useWindowDimensions
hook to make layout decisions. However, this approach falls short in situations where we need to maintain the same layout for both mobile devices and the Right-Hand Panel (RHP) on wide screens. As a result, we resort to hard-coded solutions or utilize different methods, which leads to code inconsistency and maintainability challenges.
The root cause of this problem lies in the absence of a dedicated mechanism to determine the layout based on specific conditions, such as whether a screen is within the RHP or on a small screen.
isInRHP
:Include an isInRHP option with a default value (true). This initial param will allow screens to determine whether they are within the Right-Hand Panel (RHP) and make layout decisions accordingly.
<ModalStackNavigator.Screen
key={name}
name={name}
getComponent={(screens as Required<Screens>)[name as Screen]}
initialParams={{isInRHP: true} as TStackParams[string]} //here
/>
useResponsiveLayout
Custom Hook: Develop a custom hook called useResponsiveLayout
that provides a unified way to determine the appropriate layout. This hook will take advantage of useWindowDimensions
and the isInRHP
route prop to decide whether a narrow layout should be used. The hook's implementation is as follows:
export default function useResponsiveLayout(): ResponsiveLayoutResult {
const {isSmallScreenWidth} = useWindowDimensions();
try {
const {params} = useRoute<RouteProp<RouteParams, 'params'>>();
return {shouldUseNarrowLayout: isSmallScreenWidth || (params?.isInRHP ?? false)};
} catch (error) {
return {
shouldUseNarrowLayout: isSmallScreenWidth,
};
}
}
useWindowDimensions
with useResponsiveLayout
: Update the codebase to replace most instances where useWindowDimensions
is used for layout decisions with useResponsiveLayout
as follows:Before:
const { isSmallScreenWidth } = useWindowDimensions();
After:
const { shouldUseNarrowLayout } = useResponsiveLayout();
isSmallScreenWidth
from useWindowDimensions
for layout determination. This rule will encourage developers to use 'shouldUseNarrowLayout' from useResponsiveLayout
instead, ensuring consistency in layout decisions throughout the codebase.const _ = require('underscore');
const message = require('./CONST').MESSAGE.PREFER_USE_RESPONSIVE_FOR_LAYOUT;
module.exports = {
meta: {
type: 'problem',
docs: {
description: 'Prohibit the direct use of isSmallScreenWidth from useWindowDimensions',
},
},
create(context) {
return {
VariableDeclarator(node) {
if (!node.init || !node.init.callee || node.init.callee.name !== 'useWindowDimensions') {
return;
}
// Check for 'const {isSmallScreenWidth, ...} = useWindowDimensions();' pattern
if (node.id.type === 'ObjectPattern') {
node.id.properties.forEach((property) => {
if (!property.key || property.key.name !== 'isSmallScreenWidth') {
return;
}
context.report({
node: property,
message,
});
});
}
// Check for 'const var = useWindowDimensions();' and use of this var
const variableName = node.id.name;
const variableUsages = _.filter(context.getScope().references, reference => reference.identifier.name === variableName);
variableUsages.forEach((usage) => {
const parent = usage.identifier.parent;
// Check for 'const isSmallScreen = var.isSmallScreenWidth;' pattern
if (parent.type === 'MemberExpression' && parent.property.name === 'isSmallScreenWidth') {
context.report({
node: parent.property,
message,
});
}
// Check for 'const {isSmallScreenWidth} = var;' pattern
if (parent.type === 'VariableDeclarator' && parent.id.type === 'ObjectPattern') {
parent.id.properties.forEach((property) => {
if (!property.key || property.key.name !== 'isSmallScreenWidth') {
return;
}
context.report({
node: property,
message,
});
});
}
});
},
MemberExpression(node) {
// Check for 'const isSmallScreen = useWindowDimensions().isSmallScreenWidth;' pattern
if (node.object.type !== 'CallExpression' || node.object.callee.name !== 'useWindowDimensions' || node.property.name !== 'isSmallScreenWidth') {
return;
}
context.report({
node,
message,
});
},
};
},
};
we should also add a test for this rule.
N/A
Problem: In the current application, there is a challenge when needing to use the same layout for both mobile devices and the right-hand panel (RHP) on wide screens. This problem arises because it's not always feasible to rely on the isSmallScreenWidth variable from useWindowDimensions to determine which layout to use. As a result, developers often resort to hard-coded and inconsistent solutions to address this issue.
Solution: To address this problem, the following changes are proposed:
Route Prop for RHP Detection: In the navigation stack, it is suggested to add an isInRHP route prop to all screens within the RHP. This addition allows for easy identification of screens within the RHP.
Custom Hook - useResponsiveLayout: Create a custom hook called useResponsiveLayout to determine the appropriate layout based on the screen width and the isInRHP route prop.
function useResponsiveLayout() {
const { isSmallScreenWidth } = useWindowDimensions();
const { params } = useRoute();
return {
shouldUseNarrowLayout: isSmallScreenWidth || params.isInRHP,
};
}
Replace useWindowDimensions with useResponsiveLayout: To ensure a consistent approach to layout handling, replace most of the current uses of useWindowDimensions with useResponsiveLayout as shown below:
// Before
const { isSmallScreenWidth } = useWindowDimensions();
// After
const { shouldUseNarrowLayout } = useResponsiveLayout();
Introduce a Lint Rule: To maintain code quality and consistency, introduce a new lint rule that discourages the use of isSmallScreenWidth from useWindowDimensions. Developers are advised to use shouldUseNarrowLayout instead.
This proposed solution aims to provide a more unified and maintainable approach to handling responsive layouts in the application. These changes simplify the management of layouts across various screen sizes and ensure a more consistent user experience.
📣 @WebflowGuru! 📣 Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork. Please follow these steps:
Contributor details
Your Expensify account email: <REPLACE EMAIL HERE>
Upwork Profile Link: <REPLACE LINK HERE>
Thanks for all the proposals everyone. At this time I've decided to move forward with the one that feels the clearest and most high-quality, which in my opinion is from @rayane-djouah here.
Thank you, I will raise a PR asap
@rayane-djouah any updates?
Updating now
can someone provide an update on the status of this issue? thanks!
PR still in review by C+
Since we're splitting this up into a few PRs, @rayane-djouah, can you lay out the related PRs in sequence please?
Based on the changes in this PR https://github.com/Expensify/App/pull/31476, we're splitting this up into several PRs as follows:
useResponsiveLayout
.
https://github.com/Expensify/App/pull/33425isInRHP
prop. https://github.com/Expensify/App/pull/33426useResponsiveLayout
hook in https://github.com/Expensify/App/pull/34743.
Instead of passing a parameter to screens in the modal stack navigator and checking for it in the hook, I am now obtaining the navigator name directly from the navigationRef in the hook without altering the navigation logic.)shouldShowSmallScreen
and isInModal
props in components.
https://github.com/Expensify/App/pull/34837isSmallScreenWidth
from useWindowDimensions
in components
folder files.
https://github.com/Expensify/App/pull/36292isSmallScreenWidth
from useWindowDimensions
in pages
folder files.
https://github.com/Expensify/App/pull/43961isSmallScreenWidth
from useWindowDimensions
in libs
folder files.
https://github.com/Expensify/App/pull/36294~~isSmallScreenWidth
prop from the withWindowDimensions
HOC in functional components.
https://github.com/Expensify/App/pull/36295~~isSmallScreenWidth
parameter names in various functions (which doesn't have much effect).
https://github.com/Expensify/App/pull/36296~~useWindowDimensions
with useResponsiveLayout
, refactor useWindowDimensions
to export windowWidth
and windowHeight
only, and make useResponsiveLayout
responsible for any logic determining the correct layout.
https://github.com/Expensify/App/pull/46788shouldUseNarrowLayout
over isSmallScreenWidth
from useResponsiveLayout
, with a warning level. https://github.com/Expensify/eslint-config-expensify/pull/116eslint
in App
to use the new lint rule. We might also include necessary changes after introducing the ruleUpwork job price has been updated to $1000
Doubling the bounty here due to large scope
Reviewing
label has been removed, please complete the "BugZero Checklist".
The solution for this issue has been :rocket: deployed to production :rocket: in version 1.4.21-4 and is now subject to a 7-day regression period :calendar:. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2024-01-11. :confetti_ball:
After the hold period is over and BZ checklist items are completed, please complete any of the applicable payments for this issue, and check them off once done.
For reference, here are some details about the assignees on this issue:
BugZero Checklist: The PR adding this new feature has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:
moving to daily since payment is coming up soon
@maddylewis since we are splitting the PR into multiple small PRs we should only process payment once the last PR gets merged. this is only the first one.
Agreed. Left some comments on the 2nd PR.
@rayane-djouah we're awaiting changes in the 2nd PR
sorry for the delay, I updated the PR now
Issue is ready for payment but no BZ is assigned. @alexpensify you are the lucky winner! Please verify the payment summary looks correct and complete the checklist. Thanks!
Based on this comment here, this one is not ready for payment and there is an upcoming PR that needs to go to production before I can move forward with the payment process.
For now, I updated the Upwork job link:
https://www.upwork.com/jobs/~0123a7c663aaab8163
@getusha and @rayane-djouah -- please apply and we can be ready for the payment date.
Heads up, I will be offline until Tuesday, but will catch up then to identify the status of the last PR. I will not be actively watching over this GitHub during that period. If anything urgent is needed here, please ask for help in the Open Source Slack Room-- thanks!
⚠️ Looks like this issue was linked to a Deploy Blocker here
If you are the assigned CME please investigate whether the linked PR caused a regression and leave a comment with the results.
If a regression has occurred and you are the assigned CM follow the instructions here.
If this regression could have been avoided please consider also proposing a recommendation to the PR checklist so that we can avoid it in the future.
@getusha two requests:
Please apply to the Upwork job: https://www.upwork.com/jobs/~0123a7c663aaab8163
Can we get feedback if this Deploy Blocker notice is accurate to the first PR or unrelated to this GH? Thanks!
The solution for this issue has been :rocket: deployed to production :rocket: in version 1.4.25-10 and is now subject to a 7-day regression period :calendar:. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2024-01-24. :confetti_ball:
For reference, here are some details about the assignees on this issue:
BugZero Checklist: The PR adding this new feature has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:
I updated the approach here cc @getusha @roryabraham
@getusha and @roryabraham - to confirm, this one is pending one last PR, so the January 24 payment date is inaccurate - right? Thanks!
Yes, there's more than 1 outstanding PR. This should not be awaiting payment yet.
@getusha any update on when you'll be able to review this? It's not particularly high-priority, but better to not have it drag on longer than necessary. If you're currently prioritizing something else, that might be ok – just try to communicate a bit more actively. Thanks!
Thank you for confirming!
@alexpensify here is a list of PRs we should complete before payment https://github.com/Expensify/App/issues/30528#issuecomment-1868485991
@rayane-djouah @roryabraham i think we should avoid putting the issue link on upcoming PRs to make the automation stop triggering.
Thank you for this update and noted!
@rayane-djouah when do you think you'll be able to raise the next PR?
PR raised @getusha
Thanks, will try to complete the review tomorrow.
@rayane-djouah @getusha just checking in here – how are we doing and what are our next steps?
Looks like @rayane-djouah needs to update https://github.com/Expensify/App/pull/34837 to resolve some merge conflicts. Anything else?
needs to update https://github.com/Expensify/App/pull/34837 to resolve some merge conflicts. Anything else?
Yes, @rayane-djouah will complete the checklist & resolve conflicts.
updated the PRs list
Looks like we are making progress here!
Weekly Update: Making progress
Weekly Update: @rayane-djouah some of the PRs are still in draft mode
Can we get an update in the PR list you put together here - https://github.com/Expensify/App/issues/30528#issuecomment-1868485991
Thanks!
https://github.com/Expensify/App/pull/36292 still in review
The PR listed above is still in review
Slack context: https://expensify.slack.com/archives/C01GTK53T8Q/p1698364514493649
Problem
There are some times when we want to use the same layout on mobile devices or in the RHP on wide screens. In these cases, we can't rely on
isSmallScreenWidth
fromuseWindowDimensions
to determine which layout to use, so we have hard-coded and/or different solutions we use to address the same problem.Solution
In the navigation stack, add an
isInRHP
route prop to all screens in the RHP.Write a custom hook called
useResponsiveLayout
that does something like this:Replace most layout-motivated uses of useWindowDimensions with useResponsiveLayout like so:
Introduce a new lint rule that prohibits using
isSmallScreenWidth
fromuseWindowDimensions
, advising developers to useshouldUseNarrowLayout
instead.Upwork Automation - Do Not Edit