Skip to content
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

refactor: Root screen to functional component #502

Merged
merged 12 commits into from
Feb 29, 2024
Merged

Conversation

tuliomir
Copy link
Collaborator

@tuliomir tuliomir commented Jan 31, 2024

Acceptance Criteria

  • Refactors the Root component inside App.js to a functional component
  • Refactors the Version component, called uniquely by Root, to a functional component
  • Refactors the VersionError component, called uniquely by Root, to a functional component
  • Adapts the event handling codes to work with useEffect()

Security Checklist

  • Make sure you do not include new dependencies in the project unless strictly necessary and do not include dev-dependencies as production ones. More dependencies increase the possibility of one of them being hijacked and affecting us.

@tuliomir tuliomir self-assigned this Jan 31, 2024
Copy link

codecov bot commented Jan 31, 2024

Codecov Report

Attention: Patch coverage is 0% with 69 lines in your changes are missing coverage. Please review.

Project coverage is 9.20%. Comparing base (e09124a) to head (a160da3).
Report is 2 commits behind head on dev.

❗ Current head a160da3 differs from pull request most recent head 9d1755f. Consider uploading reports for the commit 9d1755f to get more accurate results

Files Patch % Lines
src/App.js 0.00% 44 Missing and 13 partials ⚠️
src/screens/VersionError.js 0.00% 6 Missing ⚠️
src/components/Version.js 0.00% 4 Missing ⚠️
src/screens/Server.js 0.00% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             dev    #502      +/-   ##
========================================
- Coverage   9.21%   9.20%   -0.02%     
========================================
  Files        112     112              
  Lines       5250    5259       +9     
  Branches     695     698       +3     
========================================
  Hits         484     484              
- Misses      4106    4112       +6     
- Partials     660     663       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@tuliomir tuliomir changed the title refactor: Functional root component refactor: Root screen to functional component Jan 31, 2024
@tuliomir tuliomir force-pushed the refactor/functional-root branch from ff07415 to 009556c Compare February 2, 2024 18:44
@tuliomir tuliomir marked this pull request as ready for review February 2, 2024 18:49
@tuliomir tuliomir removed the request for review from pedroferreira1 February 2, 2024 18:49
}
}
}, [isVersionAllowed, wallet]);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version validation used to be inside the returnDefaultComponent function, but was moved up to the Root level to reduce the amount of times it was called during the application runtime.

Comment on lines +332 to 334
if (!versionIsKnown) {
if (!isLockedScreen) {
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't understand it. Shouldn't it return at least an error page?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This indeed is still confusing. I believe the outer navigation and outer wrappers should be refactored in a future moment for increased legibility.

Added some more documentation on ae60eeb, but in short: this screen should not render anything while the version is still unknown.

The response from the fullnode informing the version should be received in a fraction of a second, so this will normally not be an issue. Connection failures with the fullnode during this request should be intercepted by the <ErrorWrapper /> component

src/App.js Outdated
Comment on lines 100 to 128
if (!IPC_RENDERER) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case I think we should keep the IPC_RENDERER logic inside the if statement.
This is because we may want to add more logic to the startup and if we add after this it may cause some unintended issues.
Another reason is that the return of an useEffect is special, and if we add some cleanup logic in the return in the end it may not work all the time since we have an early return here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. Refactored on 74bab60.

src/App.js Outdated
});
}
});
// If there is no ledger connected, finish execution here
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IPC_RENDERER does not signal if a ledger is connected.
electron usually runs with 2 processes a main (with nodeJS on the host) and a renderer (with the frontend code on a browser) and there is a special IPC (inter-process communication) channel between those 2, the main side will have a IPC_MAIN and the renderer side a IPC_RENDERER.

There is a case where this channel does not exist, when we start the renderer code on a normal browser instead of the electron one, this is why no IPC_RENDERER means no ledger, but no IPC_RENDERER does not mean no ledger connected

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improved the description on 74bab60.

useEffect(() => {
// Fetch the version information before rendering any screens, if possible
if (isVersionAllowed === undefined && wallet) {
helpersUtils.loadStorageState();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is better kept in the initial startup.
What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already as close to the initial startup as I could move it while being in context, because it needs an initialized wallet to check the API version.

If I moved this into the ErrorWrapper, ErrorBoundary it would seem to be out of place, I think.
Do you agree?


// We already handle all js errors in general and open an error modal to the user
// so there is no need to catch the promise error below
versionUtils.checkApiVersion(wallet);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we check if this should also run when we change server?
Because the method logic does 2 things, validate that the fullnode connected is compatible with our wallet version and set the network.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense. On 51dc965 I modified the Server.js logic to reset the isVersionAllowed property, triggering a new validation from this effect.

@tuliomir tuliomir requested a review from r4mmer February 8, 2024 15:11
Comment on lines 208 to 210

// Forces the validation of the allowed version
dispatch(isVersionAllowedUpdate({ allowed: undefined }));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this solution but can you double check that the server change flow is not affected?
For instance, we have:

  • Change server from mainnet to another in mainnet
  • Change server from mainnet to testnet successfully
  • Change server from mainnet to testnet and fail the testnet confirm modal
  • Change server from testnet to another in testnet
  • Change server from testnet to mainnet

Since we are changing a variable that may change the current screen I think this is important.

Copy link
Collaborator Author

@tuliomir tuliomir Feb 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All those were working OK, but the dispatch was not being done on an optimal place.
Refactored it to inside the executeServerChange() method on a160da3.

src/App.js Outdated
throw new Error('[LoadedWalletComponent] isVersionAllowed is undefined');
// return <Redirect to={{
// pathname: '/loading_addresses/',
// state: {path: match.url},
// waitVersionCheck: true
// }} />;
// The version information is not yet available, no op
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because when the ServerChange sets the isVersionAllowed to undefined to force a revalidation of the version, the LoadedWalletComponent would throw an exception and the whole application would come to a halt.

Instead, it should just wait a few more fractions of a second for this property to be populated and the app can continue working normally.

Comment on lines +139 to +148
useEffect(() => {
// Fetch the version information before rendering any screens, if possible
if (isVersionAllowed === undefined && wallet) {
helpersUtils.loadStorageState();

// We already handle all js errors in general and open an error modal to the user
// so there is no need to catch the promise error below
versionUtils.checkApiVersion(wallet);
}
}, [isVersionAllowed, wallet]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkApiVersion is an async method with a state change, I think we should write this useEffect more like whats described here what do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed, this is an important change and will be made on a dedicaded PR. I'll open an issue for that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@r4mmer r4mmer self-requested a review February 8, 2024 15:58
@tuliomir tuliomir force-pushed the refactor/functional-root branch from 01fbbbb to a160da3 Compare February 8, 2024 18:37
@tuliomir tuliomir merged commit 5df5b77 into dev Feb 29, 2024
@tuliomir tuliomir deleted the refactor/functional-root branch February 29, 2024 12:58
@tuliomir tuliomir mentioned this pull request Mar 22, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants