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

Refactored to add AmazonQView parent class containing common setup #11

Merged
merged 8 commits into from
Sep 17, 2024
Merged
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