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

Integrate browser based views in ViewContainer #359

Merged
merged 20 commits into from
Feb 12, 2025

Conversation

taldekar
Copy link
Contributor

@taldekar taldekar commented Feb 10, 2025

Issue #336

Description of changes:

  • Integrated independently registered AmazonQChatWebView and ToolkitLoginWebView into the AmazonQViewContainer class.
  • Wired up the ViewRouter in the Activator without methods to interact with it since it functions autonomously through the EventBroker.
  • Wire up the ViewRouter to determine the view shown based on the order of resolution.
  • Updated the AmazonQView abstract class to extend the BaseAmazonQView instead of a ViewPart. Added functionality to pass the IViewSite in, which required to setup the AmazonQCommonActions.
  • Track subscriptions in AmazonQView, so they can be disposed with the browser.
  • Added a focus listener to the parent composite to transfer focus from the parent composite to the browser when focus is gained.
  • Added a fair semaphore to the AmazonQViewContainer to ensure that createPartControl's updateChildView call and the another simultaneous updateChildView call from the event observer in the class do leave the plugin in an inconsistent state due to race conditions.
  • Removed view routing logic and auth state listener from the ReauthenticateView.
  • Removed logic to handle mutually exclusive views from the ViewVisibilityManager. The calls now simply use showView.
  • Updated AmazonQCommonActions to not require auth state to be passed in during initialization. The state is automatically received when the actions subscribe to the event broker.
  • Refactored actions to remove redundant updateVisibility call with AuthState as parameter.
  • Added an AuthState listener to the ToggleAutoTriggerContributionItem to avoid passing in state during initialization.
  • Updated AmazonQBrowserProviderTest that was failing due to calls to Eclipse Display, which isn't available during unit tests. This method that creates a composite to test browser compatibility was stubbed out and does not run. This method is therefore also not tested, because the method doesn't work with mocked Composites.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@taldekar taldekar changed the base branch from main to taldekar/AssetProviders February 10, 2025 20:06
@taldekar taldekar changed the base branch from taldekar/AssetProviders to feature/viewRefactor February 10, 2025 22:21
@taldekar taldekar requested a review from breedloj February 10, 2025 22:33
Comment on lines +10 to +20
public boolean hasFailed() {
return this == FAILED;
}

public boolean isActive() {
return this == ACTIVE;
}

public boolean isPending() {
return this == PENDING;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Unless we anticipate these checks becoming more dynamic I don't see the value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, I'll make the change.

Comment on lines 29 to 31
Optional<String> content = getContent();
Activator.getEventBroker().post(WebViewAssetState.class,
content.isPresent() ? WebViewAssetState.RESOLVED : WebViewAssetState.DEPENDENCY_MISSING);
Copy link
Contributor

Choose a reason for hiding this comment

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

It is typically bad practice to have constructors performing business logic beyond basic instantiation and member assignment. These seem like tasks suited for an explicit initializer method. That seems like something that can be pushed to the base class since the login webview is doing the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. I'll move it to an initializer method. Would I call this method from whatever class is using the asset provider. Also, this logic is updated in the latest change, so it would be difficult to move this to the base class after #361.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in #361.

@@ -105,16 +96,20 @@ private void updateChildView() {
layout.topControl = newViewComposite;
parentComposite.layout(true, true);

activeView = newView;
currentView = newView;
containerLock.unlock();
Copy link
Contributor

Choose a reason for hiding this comment

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

Use caution here: if for any reason this code is never reached (for instance, an exception is thrown executing the logic in this critical section) then you will end up deadlocking the component. Good practice is for this code to run in a try block and the unlock in a finally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, that makes sense. I didn't think about that. I'll make the change.

Comment on lines +37 to +49
public Composite setupView(final Composite parent) {
super.setupView(parent);

setupParentBackground(parent);
var result = setupBrowser(parent);
// if setup of amazon q view fails due to missing webview dependency, switch to
// that view
// and don't setup rest of the content

if (!result) {
showDependencyMissingView("update");
return;
return parent;
}
var browser = getBrowser();

addFocusListener(parent, browser);

Copy link
Contributor

Choose a reason for hiding this comment

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

A lot of this logic can probably also be moved to the base class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll look into this.

@taldekar taldekar merged commit c29e968 into feature/viewRefactor Feb 12, 2025
@taldekar taldekar deleted the taldekar/IntegrateBrowserBasedViews branch February 12, 2025 18:52
taldekar added a commit that referenced this pull request Feb 25, 2025
* Pass populated AWS_CA_BUNDLE env var to Flare (#341)

* Add UI notification to alert user of deprecated manifest version (#312)

* Revert commit 'Add UI notification to alert user of deprecated manifest version'

* Revert 'Pass populated AWS_CA_BUNDLE env var to Flare'

* Rebase changes from Browser Provider PR

* Fix ViewRouter

* Integrate browser based views in ViewContainer

* Fix checkstyle issues

* Fix AmazonQBrowserProvider tests

* Fix bug due to display sync exec call

* Add semaphore locking to container to prevent race conditions

* Add browser focus handling

* Add state checking methods to LspState

* Clean up code

* Remove unnecessary parent assignment from chat webview

* Refactor ViewVisibilityManager to default to one view

* Add accidentally removed telemetry emissions

* Update plugin descriptor (#360)

* Move semaphore locking/unlocking to try/finally block

---------

Co-authored-by: Jonathan Breedlove <[email protected]>
Co-authored-by: Nicolas <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants