Skip to content

Commit 1392775

Browse files
committed
feat: display notification on plugin updates
1 parent 10b090e commit 1392775

File tree

8 files changed

+125
-4
lines changed

8 files changed

+125
-4
lines changed

src/main/java/ee/carlrobert/codegpt/CodeGPTPlugin.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
import com.intellij.ide.plugins.PluginManagerCore;
66
import com.intellij.openapi.application.PathManager;
77
import com.intellij.openapi.extensions.PluginId;
8+
import com.intellij.openapi.progress.ProgressIndicator;
89
import com.intellij.openapi.project.Project;
9-
import ee.carlrobert.codegpt.telemetry.core.util.Directories;
10+
import com.intellij.openapi.updateSettings.impl.PluginDownloader;
11+
import com.intellij.openapi.updateSettings.impl.UpdateChecker;
1012
import java.io.File;
1113
import java.nio.file.Path;
1214
import java.nio.file.Paths;
15+
import java.util.Collection;
16+
import java.util.Optional;
1317
import org.jetbrains.annotations.NotNull;
1418

1519
public final class CodeGPTPlugin {
@@ -46,4 +50,18 @@ private CodeGPTPlugin() {
4650
public static @NotNull String getProjectIndexStorePath(@NotNull Project project) {
4751
return getIndexStorePath() + File.separator + project.getName();
4852
}
53+
54+
public static Optional<PluginDownloader> tryFindAvailableUpdate(
55+
@NotNull ProgressIndicator indicator) {
56+
return findAvailableUpdates(indicator).stream()
57+
.filter((update) -> CODEGPT_ID.equals(update.getId()))
58+
.findFirst();
59+
}
60+
61+
private static @NotNull Collection<PluginDownloader> findAvailableUpdates(
62+
@NotNull ProgressIndicator indicator) {
63+
return UpdateChecker.getInternalPluginUpdates(null, indicator)
64+
.getPluginUpdates()
65+
.getAllEnabled();
66+
}
4967
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package ee.carlrobert.codegpt;
2+
3+
import com.intellij.notification.NotificationAction;
4+
import com.intellij.notification.NotificationType;
5+
import com.intellij.openapi.application.ApplicationManager;
6+
import com.intellij.openapi.progress.ProgressIndicator;
7+
import com.intellij.openapi.progress.Task;
8+
import com.intellij.openapi.project.Project;
9+
import com.intellij.openapi.startup.StartupActivity;
10+
import com.intellij.openapi.updateSettings.impl.UpdateChecker;
11+
import com.intellij.openapi.updateSettings.impl.UpdateSettings;
12+
import com.intellij.util.concurrency.AppExecutorUtil;
13+
import ee.carlrobert.codegpt.settings.configuration.ConfigurationState;
14+
import ee.carlrobert.codegpt.util.OverlayUtil;
15+
import java.util.concurrent.TimeUnit;
16+
import org.jetbrains.annotations.NotNull;
17+
18+
public class CodeGPTUpdateStartupActivity implements StartupActivity.Background {
19+
20+
@Override
21+
public void runActivity(@NotNull Project project) {
22+
schedulePluginUpdateChecks(project);
23+
}
24+
25+
private void schedulePluginUpdateChecks(Project project) {
26+
AppExecutorUtil.getAppScheduledExecutorService().scheduleWithFixedDelay(() -> {
27+
if (project != null && ConfigurationState.getInstance().isCheckForPluginUpdates()) {
28+
new CheckForUpdatesTask(project).queue();
29+
}
30+
31+
}, 0, 4L, TimeUnit.HOURS);
32+
}
33+
34+
private static class CheckForUpdatesTask extends Task.Backgroundable {
35+
36+
public CheckForUpdatesTask(@NotNull Project project) {
37+
super(project, CodeGPTBundle.get("checkForUpdatesTask.title"), true);
38+
}
39+
40+
private static void installCodeGPTUpdate(Project project) {
41+
var settingsCopy = new UpdateSettings();
42+
var settingsState = settingsCopy.getState();
43+
settingsState.copyFrom(UpdateSettings.getInstance().getState());
44+
settingsState.setCheckNeeded(true);
45+
settingsState.setPluginsCheckNeeded(true);
46+
settingsState.setShowWhatsNewEditor(true);
47+
settingsState.setThirdPartyPluginsAllowed(true);
48+
UpdateChecker.updateAndShowResult(project, settingsCopy);
49+
}
50+
51+
public void run(@NotNull ProgressIndicator indicator) {
52+
if (!myProject.isDisposed()) {
53+
CodeGPTPlugin.tryFindAvailableUpdate(indicator)
54+
.ifPresent((update) -> OverlayUtil.getDefaultNotification(
55+
CodeGPTBundle.get("checkForUpdatesTask.notification.message"),
56+
NotificationType.IDE_UPDATE)
57+
.addAction(NotificationAction.createSimpleExpiring(
58+
CodeGPTBundle.get("checkForUpdatesTask.notification.installButton"),
59+
() -> ApplicationManager.getApplication()
60+
.executeOnPooledThread(() -> installCodeGPTUpdate(myProject))))
61+
.addAction(NotificationAction.createSimpleExpiring(
62+
CodeGPTBundle.get("checkForUpdatesTask.notification.hideButton"),
63+
() -> ConfigurationState.getInstance().setCheckForPluginUpdates(false)))
64+
.notify(myProject));
65+
}
66+
}
67+
}
68+
}

src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class ConfigurationComponent {
4141

4242
private final JPanel mainPanel;
4343
private final JBTable table;
44+
private final JBCheckBox checkForPluginUpdatesCheckBox;
4445
private final JBCheckBox openNewTabCheckBox;
4546
private final JBCheckBox methodNameGenerationCheckBox;
4647
private final JBCheckBox autoFormattingCheckBox;
@@ -99,6 +100,9 @@ public void changedUpdate(DocumentEvent e) {
99100
systemPromptTextArea.setColumns(60);
100101
systemPromptTextArea.setRows(3);
101102

103+
checkForPluginUpdatesCheckBox = new JBCheckBox(
104+
CodeGPTBundle.get("configurationConfigurable.checkForPluginUpdates.label"),
105+
configuration.isCheckForPluginUpdates());
102106
openNewTabCheckBox = new JBCheckBox(
103107
CodeGPTBundle.get("configurationConfigurable.openNewTabCheckBox.label"),
104108
configuration.isCreateNewChatOnEachAction());
@@ -112,6 +116,7 @@ public void changedUpdate(DocumentEvent e) {
112116
mainPanel = FormBuilder.createFormBuilder()
113117
.addComponent(tablePanel)
114118
.addVerticalGap(4)
119+
.addComponent(checkForPluginUpdatesCheckBox)
115120
.addComponent(openNewTabCheckBox)
116121
.addComponent(methodNameGenerationCheckBox)
117122
.addComponent(autoFormattingCheckBox)
@@ -256,6 +261,14 @@ public void setMaxTokens(int maxTokens) {
256261
maxTokensField.setValue(maxTokens);
257262
}
258263

264+
public boolean isCheckForPluginUpdates() {
265+
return checkForPluginUpdatesCheckBox.isSelected();
266+
}
267+
268+
public void setCheckForPluginUpdates(boolean checkForUpdates) {
269+
checkForPluginUpdatesCheckBox.setSelected(checkForUpdates);
270+
}
271+
259272
public boolean isCreateNewChatOnEachAction() {
260273
return openNewTabCheckBox.isSelected();
261274
}

src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationConfigurable.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public boolean isModified() {
3737
|| configurationComponent.getMaxTokens() != configuration.getMaxTokens()
3838
|| configurationComponent.getTemperature() != configuration.getTemperature()
3939
|| !configurationComponent.getSystemPrompt().equals(configuration.getSystemPrompt())
40+
|| configurationComponent.isCheckForPluginUpdates()
41+
!= configuration.isCheckForPluginUpdates()
4042
|| configurationComponent.isCreateNewChatOnEachAction()
4143
!= configuration.isCreateNewChatOnEachAction()
4244
|| configurationComponent.isMethodNameGenerationEnabled()
@@ -52,6 +54,7 @@ public void apply() {
5254
configuration.setMaxTokens(configurationComponent.getMaxTokens());
5355
configuration.setTemperature(configurationComponent.getTemperature());
5456
configuration.setSystemPrompt(configurationComponent.getSystemPrompt());
57+
configuration.setCheckForPluginUpdates(configurationComponent.isCheckForPluginUpdates());
5558
configuration.setCreateNewChatOnEachAction(
5659
configurationComponent.isCreateNewChatOnEachAction());
5760
configuration.setMethodNameGenerationEnabled(
@@ -67,6 +70,7 @@ public void reset() {
6770
configurationComponent.setMaxTokens(configuration.getMaxTokens());
6871
configurationComponent.setTemperature(configuration.getTemperature());
6972
configurationComponent.setSystemPrompt(configuration.getSystemPrompt());
73+
configurationComponent.setCheckForPluginUpdates(configuration.isCheckForPluginUpdates());
7074
configurationComponent.setCreateNewChatOnEachAction(
7175
configuration.isCreateNewChatOnEachAction());
7276
configurationComponent.setDisableMethodNameGeneration(

src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class ConfigurationState implements PersistentStateComponent<Configuratio
2020
private String systemPrompt = COMPLETION_SYSTEM_PROMPT;
2121
private int maxTokens = 1000;
2222
private double temperature = 0.1;
23+
private boolean checkForPluginUpdates = true;
2324
private boolean createNewChatOnEachAction;
2425
private boolean ignoreGitCommitTokenLimit;
2526
private boolean methodNameGenerationEnabled = true;
@@ -81,6 +82,14 @@ public void setTableData(Map<String, String> tableData) {
8182
this.tableData = tableData;
8283
}
8384

85+
public boolean isCheckForPluginUpdates() {
86+
return checkForPluginUpdates;
87+
}
88+
89+
public void setCheckForPluginUpdates(boolean checkForPluginUpdates) {
90+
this.checkForPluginUpdates = checkForPluginUpdates;
91+
}
92+
8493
public boolean isIgnoreGitCommitTokenLimit() {
8594
return ignoreGitCommitTokenLimit;
8695
}

src/main/java/ee/carlrobert/codegpt/util/OverlayUtil.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@
3535

3636
public class OverlayUtil {
3737

38+
public static Notification getDefaultNotification(String content, NotificationType type) {
39+
return new Notification("CodeGPT Notification Group", "CodeGPT", content, type);
40+
}
41+
3842
public static void showNotification(String content, NotificationType type) {
39-
Notifications.Bus.notify(
40-
new Notification("CodeGPT Notification Group", "CodeGPT", content, type));
43+
Notifications.Bus.notify(getDefaultNotification(content, type));
4144
}
4245

4346
public static int showFileStructureDialog(

src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
</projectListeners>
1111

1212
<extensions defaultExtensionNs="com.intellij">
13+
<postStartupActivity implementation="ee.carlrobert.codegpt.CodeGPTUpdateStartupActivity"/>
1314
<postStartupActivity implementation="ee.carlrobert.codegpt.PluginStartupActivity"/>
1415
<applicationConfigurable id="settings.codegpt" parentId="tools" displayName="CodeGPT"
1516
instance="ee.carlrobert.codegpt.settings.SettingsConfigurable"/>

src/main/resources/messages/codegpt.properties

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ configurationConfigurable.table.header.actionColumnLabel=Action
6666
configurationConfigurable.table.header.promptColumnLabel=Prompt
6767
configurationConfigurable.table.action.revertToDefaults.text=Revert to Defaults
6868
configurationConfigurable.table.action.addKeymap.text=Add Shortcut
69+
configurationConfigurable.checkForPluginUpdates.label=Check for plugin updates automatically
6970
configurationConfigurable.openNewTabCheckBox.label=Open a new chat on each action
7071
configurationConfigurable.enableMethodNameGeneration.label=Enable method name lookup suggestions
7172
configurationConfigurable.autoFormatting.label=Enable automatic code formatting
@@ -128,4 +129,8 @@ service.llama.title=LLaMA C/C++ Port (Free, Local)
128129
validation.error.fieldRequired=This field is required.
129130
validation.error.invalidEmail=The email you entered is invalid.
130131
validation.error.mustBeNumber=Value must be number.
131-
validation.error.mustBeBetweenZeroAndOne=Value must be between 0 and 1.
132+
validation.error.mustBeBetweenZeroAndOne=Value must be between 0 and 1.
133+
checkForUpdatesTask.title=Checking for CodeGPT update...
134+
checkForUpdatesTask.notification.message=An update for CodeGPT is available.
135+
checkForUpdatesTask.notification.installButton=Install update
136+
checkForUpdatesTask.notification.hideButton=Do not show again

0 commit comments

Comments
 (0)