Skip to content

Commit

Permalink
Check login status and network availability. (openpilot-hub#42)
Browse files Browse the repository at this point in the history
* Check login status and network availability.

* Add warning display text.

* CheckStyle adjust.

* CheckStyle adjust.

* check style.

* checkstyle fix.

* Availability check logic update.

* Availability check logic update.

* code refine.

* code refine.

---------

Co-authored-by: maozhen <[email protected]>
  • Loading branch information
maozhen520 and maozhen authored Jul 15, 2024
1 parent e92ca18 commit 69b2078
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.intellij.openapi.startup.StartupActivity;
import com.zhongan.devpilot.actions.editor.popupmenu.PopupMenuEditorActionGroupUtil;
import com.zhongan.devpilot.listener.DevPilotFileEditorListener;
import com.zhongan.devpilot.network.DevPilotAvailabilityChecker;
import com.zhongan.devpilot.update.DevPilotUpdate;

import org.jetbrains.annotations.NotNull;
Expand All @@ -15,6 +16,7 @@ public void runActivity(@NotNull Project project) {
DevPilotFileEditorListener.registerListener();

new DevPilotUpdate.DevPilotUpdateTask(project).queue();
new DevPilotAvailabilityChecker(project).checkNetworkAndLogStatus();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.zhongan.devpilot.settings.DevPilotSettingsConfigurable;
import com.zhongan.devpilot.settings.state.AIGatewaySettingsState;
import com.zhongan.devpilot.statusBar.DevPilotStatusBarBaseWidget;
import com.zhongan.devpilot.statusBar.status.DevPilotStatusEnum;
import com.zhongan.devpilot.update.DevPilotUpdate;
import com.zhongan.devpilot.util.DevPilotMessageBundle;
import com.zhongan.devpilot.util.LoginUtils;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -105,4 +110,35 @@ public static void updateNotification(Project project) {
}));
Notifications.Bus.notify(notification);
}

public static void networkDownNotification(Project project) {
var notification = new Notification(
"DevPilot Notification Group",
DevPilotMessageBundle.get("notification.group.devpilot"),
DevPilotMessageBundle.get("devpilot.notification.network.message"),
NotificationType.ERROR);
DevPilotStatusBarBaseWidget.update(project, DevPilotStatusEnum.Disconnected);
notification.addAction(NotificationAction.createSimpleExpiring(DevPilotMessageBundle.get("devpilot.notification.network.setting"),
() -> ShowSettingsUtil.getInstance().showSettingsDialog(project, DevPilotSettingsConfigurable.class)));
notification.addAction(NotificationAction.createSimpleExpiring(DevPilotMessageBundle.get("devpilot.notification.hideButton"), () -> {

}));
Notifications.Bus.notify(notification);
}

public static void notLoginNotification(Project project) {
var notification = new Notification(
"DevPilot Notification Group",
DevPilotMessageBundle.get("notification.group.devpilot"),
DevPilotMessageBundle.get("devpilot.status.notLoggedIn"),
NotificationType.WARNING);
DevPilotStatusBarBaseWidget.update(project, DevPilotStatusEnum.NotLoggedIn);
notification.addAction(NotificationAction.createSimpleExpiring(DevPilotMessageBundle.get("devpilot.settings.service.statusbar.login.desc"),
() -> ApplicationManager.getApplication().executeOnPooledThread(LoginUtils::gotoLogin)));
notification.addAction(NotificationAction.createSimpleExpiring(DevPilotMessageBundle.get("devpilot.notification.hideButton"), () -> {

}));
Notifications.Bus.notify(notification);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.zhongan.devpilot.network;

import com.intellij.openapi.project.Project;
import com.zhongan.devpilot.actions.notifications.DevPilotNotification;
import com.zhongan.devpilot.enums.LoginTypeEnum;
import com.zhongan.devpilot.settings.state.AIGatewaySettingsState;
import com.zhongan.devpilot.settings.state.AvailabilityCheck;
import com.zhongan.devpilot.settings.state.DevPilotLlmSettingsState;
import com.zhongan.devpilot.statusBar.DevPilotStatusBarBaseWidget;
import com.zhongan.devpilot.statusBar.status.DevPilotStatusEnum;
import com.zhongan.devpilot.util.LoginUtils;
import com.zhongan.devpilot.util.OkhttpUtils;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import okhttp3.OkHttpClient;
import okhttp3.Request;

import static com.zhongan.devpilot.constant.DefaultConst.TRIAL_DEFAULT_HOST;

public class DevPilotAvailabilityChecker implements Runnable {

private final Project project;

private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

public DevPilotAvailabilityChecker(@NotNull Project project) {
this.project = project;
}

private void checkAndNotify() {
if (!LoginUtils.isLogin()) {
DevPilotNotification.notLoginNotification(project);
} else if (!isNetWorkAvailable()) {
DevPilotNotification.networkDownNotification(project);
} else {
DevPilotStatusBarBaseWidget.update(project, LoginUtils.isLogin() ? DevPilotStatusEnum.LoggedIn : DevPilotStatusEnum.NotLoggedIn);
}
}

private boolean isNetWorkAvailable() {
String url = getCheckUrl();
if (StringUtils.isBlank(url)) {
return false;
}
OkHttpClient client = OkhttpUtils.getClient();
Request request = new Request.Builder().url(url).build();
try {
client.newCall(request).execute();
return true;
} catch (Exception e) {
return false;
}
}

private String getCheckUrl() {
var setting = DevPilotLlmSettingsState.getInstance();
var loginType = LoginTypeEnum.getLoginTypeEnum(setting.getLoginType());
switch (loginType) {
case WX:
return TRIAL_DEFAULT_HOST;
case ZA:
case ZA_TI:
return AIGatewaySettingsState.getInstance().getModelBaseHost(null);
default:
return "";
}
}

@Override
public void run() {
if (AvailabilityCheck.getInstance().getEnable()) {
checkAndNotify();
}
}

public void checkNetworkAndLogStatus() {
if (AvailabilityCheck.getInstance().getEnable()) {
executor.scheduleAtFixedRate(this, 0, 2, TimeUnit.HOURS);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.intellij.util.ui.FormBuilder;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UI;
import com.zhongan.devpilot.settings.state.AvailabilityCheck;
import com.zhongan.devpilot.settings.state.CompletionSettingsState;
import com.zhongan.devpilot.settings.state.DevPilotLlmSettingsState;
import com.zhongan.devpilot.settings.state.LanguageSettingsState;
Expand All @@ -22,6 +23,8 @@ public class DevPilotSettingsComponent {

private final JBRadioButton autoCompletionRadio;

private final JBRadioButton statusCheckRadio;

private Integer index;

public DevPilotSettingsComponent(DevPilotSettingsConfigurable devPilotSettingsConfigurable, DevPilotLlmSettingsState settings) {
Expand All @@ -35,6 +38,8 @@ public DevPilotSettingsComponent(DevPilotSettingsConfigurable devPilotSettingsCo
autoCompletionRadio = new JBRadioButton(
DevPilotMessageBundle.get("devpilot.settings.service.code.completion.desc"),
CompletionSettingsState.getInstance().getEnable());
statusCheckRadio = new JBRadioButton(DevPilotMessageBundle.get("devpilot.settings.service.status.check.enable.desc"),
AvailabilityCheck.getInstance().getEnable());

mainPanel = FormBuilder.createFormBuilder()
.addComponent(UI.PanelFactory.panel(fullNameField)
Expand All @@ -46,6 +51,10 @@ public DevPilotSettingsComponent(DevPilotSettingsConfigurable devPilotSettingsCo
DevPilotMessageBundle.get("devpilot.settings.service.code.completion.title")))
.addComponent(autoCompletionRadio)
.addVerticalGap(8)

.addComponent(new TitledSeparator(
DevPilotMessageBundle.get("devpilot.settings.service.status.check.title")))
.addComponent(statusCheckRadio)
.addComponentFillVertically(new JPanel(), 0)
.getPanel();
}
Expand Down Expand Up @@ -86,4 +95,9 @@ public Integer getLanguageIndex() {
public boolean getCompletionEnabled() {
return autoCompletionRadio.isSelected();
}

public boolean getStatusCheckEnabled() {
return statusCheckRadio.isSelected();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.intellij.openapi.util.NlsContexts;
import com.zhongan.devpilot.actions.editor.popupmenu.PopupMenuEditorActionGroupUtil;
import com.zhongan.devpilot.enums.LoginTypeEnum;
import com.zhongan.devpilot.settings.state.AvailabilityCheck;
import com.zhongan.devpilot.settings.state.CompletionSettingsState;
import com.zhongan.devpilot.settings.state.DevPilotLlmSettingsState;
import com.zhongan.devpilot.settings.state.LanguageSettingsState;
Expand Down Expand Up @@ -42,10 +43,12 @@ public boolean isModified() {
var languageSettings = LanguageSettingsState.getInstance();
var languageIndex = settingsComponent.getLanguageIndex();
var completionEnable = CompletionSettingsState.getInstance().getEnable();
Boolean enable = AvailabilityCheck.getInstance().getEnable();

return !settingsComponent.getFullName().equals(settings.getFullName())
|| !languageIndex.equals(languageSettings.getLanguageIndex())
|| !settingsComponent.getCompletionEnabled() == (completionEnable);
|| !settingsComponent.getCompletionEnabled() == (completionEnable)
|| !settingsComponent.getStatusCheckEnabled() == (enable);
}

@Override
Expand All @@ -67,7 +70,10 @@ public void apply() throws ConfigurationException {

CompletionSettingsState completionSettings = CompletionSettingsState.getInstance();
completionSettings.setEnable(settingsComponent.getCompletionEnabled());


AvailabilityCheck availabilityCheck = AvailabilityCheck.getInstance();
availabilityCheck.setEnable(settingsComponent.getStatusCheckEnabled());

checkCodeCompletionConfig(LoginTypeEnum.getLoginTypeEnum(settings.getLoginType()));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.zhongan.devpilot.settings.state;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.util.xmlb.XmlSerializerUtil;

@State(name = "DevPilot_AvailabilityCheckSettings", storages = @Storage("DevPilot_AvailabilityCheckSettings.xml"))
public class AvailabilityCheck implements PersistentStateComponent<AvailabilityCheck> {

private Boolean enable = true;

public static AvailabilityCheck getInstance() {
return ApplicationManager.getApplication().getService(AvailabilityCheck.class);
}

public Boolean getEnable() {
return enable == null || enable;
}

public void setEnable(Boolean enable) {
this.enable = enable;
}

@Override
public AvailabilityCheck getState() {
return this;
}

@Override
public void loadState(AvailabilityCheck state) {
XmlSerializerUtil.copyBean(state, this);
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
public enum DevPilotStatusEnum {
LoggedIn,
NotLoggedIn,
InCompletion;
InCompletion,
Disconnected;

public @NotNull Icon getIcon() {
switch (this) {
Expand All @@ -30,6 +31,8 @@ public String getText() {
return DevPilotMessageBundle.get("devpilot.status.loggedIn");
case InCompletion:
return DevPilotMessageBundle.get("devpilot.status.inCompletion");
case Disconnected:
return DevPilotMessageBundle.get("devpilot.notification.network.message");
default:
return DevPilotMessageBundle.get("devpilot.status.notLoggedIn");
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
serviceImplementation="com.zhongan.devpilot.settings.actionconfiguration.EditorActionConfigurationState"/>
<applicationService serviceImplementation="com.zhongan.devpilot.settings.state.TrialServiceSettingsState"/>
<applicationService serviceImplementation="com.zhongan.devpilot.settings.state.CompletionSettingsState"/>
<applicationService serviceImplementation="com.zhongan.devpilot.settings.state.AvailabilityCheck"/>
<actionPromoter implementation="com.zhongan.devpilot.completions.inline.InlineActionsPromoter"/>
<toolWindow id="DevPilot" icon="com.zhongan.devpilot.DevPilotIcons.SYSTEM_ICON" anchor="right" doNotActivateOnStart="true" factoryClass="com.zhongan.devpilot.gui.toolwindows.DevPilotChatToolWindowFactory"/>
<projectService id="DevPilotChatToolWindowService" serviceImplementation="com.zhongan.devpilot.gui.toolwindows.chat.DevPilotChatToolWindowService"/>
Expand Down
11 changes: 10 additions & 1 deletion src/main/resources/messages/devpilot_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ devpilot.settings.service.code.completion.desc=Enable code auto completion
devpilot.settings.service.code.completion.enable.desc=Enable Code Auto Completion
devpilot.settings.service.code.completion.disabled.desc=Disabled Code Auto Completion

devpilot.settings.service.status.check.title=Status Check Configuration
devpilot.settings.service.status.check.enable.desc=Enable Status Check


devpilot.settings.service.chat.shortcut.disabled.desc=Disabled Method Shortcut
devpilot.settings.service.chat.shortcut.enable.desc=Enable Method Shortcut

Expand All @@ -79,4 +83,9 @@ devpilot.notification.hideButton=hide
devpilot.error.report=Report to Devpilot

devpilot.toolbarFeedbackAction.text=Send Feedback to DevPilot
devpilot.toolbarUserProfileAction.text=Go to User Profile
devpilot.toolbarUserProfileAction.text=Go to User Profile


devpilot.notification.network.message=Network is not available, Please check your network connection
devpilot.notification.network.setting=Go to Check Setting.

8 changes: 7 additions & 1 deletion src/main/resources/messages/devpilot_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ devpilot.settings.service.code.completion.desc=\u5F00\u542F\u4EE3\u7801\u8865\u5
devpilot.settings.service.code.completion.enable.desc=\u5F00\u542F\u4EE3\u7801\u8865\u5168
devpilot.settings.service.code.completion.disabled.desc=\u7981\u7528\u4EE3\u7801\u8865\u5168

devpilot.settings.service.status.check.title=\u7F51\u7EDC\u767B\u5F55\u72B6\u6001\u68C0\u67E5\u914D\u7F6E
devpilot.settings.service.status.check.enable.desc=\u5F00\u542F\u72B6\u6001\u68C0\u67E5

devpilot.settings.service.chat.shortcut.disabled.desc=\u7981\u7528\u65B9\u6CD5\u4E0A\u5FEB\u6377\u64CD\u4F5C
devpilot.settings.service.chat.shortcut.enable.desc=\u5F00\u542F\u65B9\u6CD5\u4E0A\u5FEB\u6377\u64CD\u4F5C

Expand All @@ -78,4 +81,7 @@ devpilot.notification.hideButton=\u9690\u85CF
devpilot.error.report=\u62A5\u544Adevpilot

devpilot.toolbarFeedbackAction.text=\u53CD\u9988
devpilot.toolbarUserProfileAction.text=\u7528\u6237\u9762\u677f
devpilot.toolbarUserProfileAction.text=\u7528\u6237\u9762\u677F

devpilot.notification.network.message=DevPilot\u8FDE\u63A5\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u540E\u91CD\u8BD5
devpilot.notification.network.setting=\u72B6\u6001\u68C0\u67E5\u914D\u7F6E

0 comments on commit 69b2078

Please sign in to comment.