Skip to content

Commit

Permalink
Refactored to add AmazonQView parent class containing common setup (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
angjordn authored Sep 17, 2024
1 parent bc75939 commit f42b759
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 186 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,55 @@

package software.aws.toolkits.eclipse.amazonq.views;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.BrowserFunction;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.part.ViewPart;

import jakarta.inject.Inject;
import software.aws.toolkits.eclipse.amazonq.lsp.manager.LspConstants;
import software.aws.toolkits.eclipse.amazonq.util.AuthUtils;
import software.aws.toolkits.eclipse.amazonq.util.PluginUtils;
import software.aws.toolkits.eclipse.amazonq.util.ThreadingUtils;
import software.aws.toolkits.eclipse.amazonq.views.actions.AmazonQCommonActions;

public class AmazonQChatWebview extends ViewPart implements ISelectionListener {
public class AmazonQChatWebview extends AmazonQView {

public static final String ID = "software.aws.toolkits.eclipse.amazonq.views.AmazonQChatWebview";

@Inject
private Shell shell;
private Browser browser;
private AmazonQCommonActions amazonQCommonActions;

private final ViewCommandParser commandParser;
private final ViewActionHandler actionHandler;

private boolean darkMode = Display.isSystemDarkTheme();

public AmazonQChatWebview() {
browser = getBrowser();
amazonQCommonActions = getAmazonQCommonActions();

this.commandParser = new LoginViewCommandParser();
this.actionHandler = new AmazonQChatViewActionHandler();
}

@Override
public final void createPartControl(final Composite parent) {
browser = new Browser(parent, SWT.NATIVE);
Display display = Display.getCurrent();
Color black = display.getSystemColor(SWT.COLOR_BLACK);
setupAmazonQView(parent, true);

browser.setBackground(black);
parent.setBackground(black);
browser.setText(getContent());
AuthUtils.isLoggedIn().thenAcceptAsync(isLoggedIn -> {
handleAuthStatusChange(isLoggedIn);
}, ThreadingUtils::executeAsyncTask);

BrowserFunction prefsFunction = new OpenPreferenceFunction(browser, "openEclipsePreferences", this::openPreferences);
browser.addDisposeListener(e -> prefsFunction.dispose());

createActions();
contributeToActionBars(getViewSite());
getSite().getPage().addSelectionListener(this);

new BrowserFunction(browser, "ideCommand") {
@Override
public Object function(final Object[] arguments) {
Expand All @@ -74,45 +62,6 @@ public Object function(final Object[] arguments) {
};
}

private void contributeToActionBars(final IViewSite viewSite) {
IActionBars bars = viewSite.getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}

private void fillLocalPullDown(final IMenuManager manager) {
manager.add(changeThemeAction);
}

private void fillLocalToolBar(final IToolBarManager manager) {
manager.add(changeThemeAction);
}

private void createActions() {
changeThemeAction = new ChangeThemeAction();
}

private Action changeThemeAction;

private class ChangeThemeAction extends Action {
ChangeThemeAction() {
setText("Change Color");
setToolTipText("Change the color");
setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ELCL_SYNCED));
}

@Override
public void run() {
darkMode = !darkMode;
browser.execute("changeTheme(" + darkMode + ");");
}
}

@Override
public final void setFocus() {
browser.setFocus();
}

private class OpenPreferenceFunction extends BrowserFunction {
private Runnable function;

Expand Down Expand Up @@ -194,9 +143,16 @@ public final void selectionChanged(final IWorkbenchPart part, final ISelection s
}

@Override
public final void dispose() {
getSite().getPage().removeSelectionListener(this);
super.dispose();
protected final void handleAuthStatusChange(final boolean isLoggedIn) {
Display.getDefault().asyncExec(() -> {
amazonQCommonActions.updateActionVisibility(isLoggedIn, getViewSite());
if (!isLoggedIn) {
browser.setText("Signed Out");
AmazonQView.showView(ToolkitLoginWebview.ID);
} else {
browser.setText(getContent());
}
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.

package software.aws.toolkits.eclipse.amazonq.views;


import java.util.Set;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import software.aws.toolkits.eclipse.amazonq.util.AuthStatusChangedListener;
import software.aws.toolkits.eclipse.amazonq.util.AuthUtils;
import software.aws.toolkits.eclipse.amazonq.util.PluginLogger;
import software.aws.toolkits.eclipse.amazonq.views.actions.AmazonQCommonActions;

public abstract class AmazonQView extends ViewPart implements ISelectionListener {

private static final Set<String> AMAZON_Q_VIEWS = Set.of(
ToolkitLoginWebview.ID,
AmazonQChatWebview.ID
);

private Browser browser;
private AmazonQCommonActions amazonQCommonActions;
private AuthStatusChangedListener authStatusChangedListener;

public static void showView(final String viewId) {
if (!AMAZON_Q_VIEWS
.contains(viewId)) {
PluginLogger.error("Failed to show view. You must add the view " + viewId + " to AMAZON_Q_VIEWS Set");
return;
}

IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
if (page != null) {
// Show requested view
try {
page.showView(viewId);
PluginLogger.info("Showing view " + viewId);
} catch (Exception e) {
PluginLogger.error("Error occurred while showing view " + viewId, e);
}

// Hide all other Amazon Q Views
IViewReference[] viewReferences = page.getViewReferences();
for (IViewReference viewRef : viewReferences) {
if (AMAZON_Q_VIEWS.contains(viewRef.getId()) && !viewRef.getId().equalsIgnoreCase(viewId)) {
try {
page.hideView(viewRef);
} catch (Exception e) {
PluginLogger.error("Error occurred while hiding view " + viewId, e);
}
}
}
}
}

public final Browser getBrowser() {
return browser;
}

public final AmazonQCommonActions getAmazonQCommonActions() {
return amazonQCommonActions;
}

protected abstract void handleAuthStatusChange(boolean isLoggedIn);

protected final void setupAmazonQView(final Composite parent, final boolean isLoggedIn) {
setupBrowser(parent);
setupActions(isLoggedIn);
setupAuthStatusListeners();
setupSelectionListener();
}

private void setupBrowser(final Composite parent) {
browser = new Browser(parent, SWT.NATIVE);
Display display = Display.getCurrent();
Color black = display.getSystemColor(SWT.COLOR_BLACK);

browser.setBackground(black);
parent.setBackground(black);
}

private void setupActions(final boolean isLoggedIn) {
amazonQCommonActions = new AmazonQCommonActions(isLoggedIn, getViewSite());
}

private void setupAuthStatusListeners() {
authStatusChangedListener = this::handleAuthStatusChange;
AuthUtils.addAuthStatusChangeListener(amazonQCommonActions.getSignoutAction());
AuthUtils.addAuthStatusChangeListener(amazonQCommonActions.getFeedbackDialogContributionAction());
}

private void setupSelectionListener() {
getSite().getPage().addSelectionListener(this);
}

@Override
public final void setFocus() {
browser.setFocus();
}

/**
* Disposes of the resources associated with this view.
*
* This method is called when the view is closed. It removes the authentication
* status change listener and the selection listener from the page.
*/
@Override
public void dispose() {
AuthUtils.removeAuthStatusChangeListener(authStatusChangedListener);
getSite().getPage().removeSelectionListener(this);
super.dispose();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ public final void handleCommand(final ParsedCommand parsedCommand, final Browser
ThreadingUtils.executeAsyncTask(() -> {
try {
AuthUtils.signIn().get();
Display.getDefault().asyncExec(() -> browser.setText("Login succeeded"));
Display.getDefault().asyncExec(() -> {
browser.setText("Login succeeded");
AmazonQView.showView(AmazonQChatWebview.ID);
});
} catch (Exception e) {
PluginLogger.error("Failed to update token", e);
}
Expand Down
Loading

0 comments on commit f42b759

Please sign in to comment.