From f29b88b37b7af979f2eb7a3b073c451cf434b223 Mon Sep 17 00:00:00 2001 From: Vadim Salavatov Date: Wed, 11 Feb 2026 18:33:00 +0100 Subject: [PATCH] IJPL-232707 refactor: extract MarketplaceSearchResultPanel GitOrigin-RevId: 937cc1e1078a218dd920ff007d7f84505b8dfee9 --- .../ide/plugins/MarketplacePluginsTab.java | 327 +++++++++--------- 1 file changed, 170 insertions(+), 157 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/MarketplacePluginsTab.java b/platform/platform-impl/src/com/intellij/ide/plugins/MarketplacePluginsTab.java index 725bf589f4a7..b815920c5c30 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/MarketplacePluginsTab.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/MarketplacePluginsTab.java @@ -476,163 +476,7 @@ class MarketplacePluginsTab extends PluginsTab { Project project = ProjectUtil.getActiveProject(); - myMarketplaceSearchPanel = - new SearchResultPanel(myCoroutineScope, marketplaceController, panel, true) { - @Override - @SuppressWarnings("unchecked") - protected void handleQuery(@NotNull String query, @NotNull PluginsGroup result, AtomicBoolean runQuery) { - int searchIndex = PluginManagerUsageCollector.updateAndGetSearchIndex(); - - SearchQueryParser.Marketplace parser = new SearchQueryParser.Marketplace(query); - - Map pluginToScore = null; - - if (parser.internal) { - try { - PluginsViewCustomizer.PluginsGroupDescriptor groupDescriptor = - PluginsViewCustomizerKt.getPluginsViewCustomizer().getInternalPluginsGroupDescriptor(); - if (groupDescriptor != null) { - if (parser.searchQuery == null) { - result.addDescriptors(groupDescriptor.getPlugins()); - } - else { - for (IdeaPluginDescriptor pluginDescriptor : groupDescriptor.getPlugins()) { - if (StringUtil.containsIgnoreCase(pluginDescriptor.getName(), parser.searchQuery)) { - result.addDescriptor(pluginDescriptor); - } - } - } - result.removeDuplicates(); - result.sortByName(); - return; - } - } - catch (Exception e) { - LOG.error("Error while loading internal plugins group", e); - } - } - - PluginModelAsyncOperationsExecutor.INSTANCE.getCustomRepositoriesPluginMap(myCoroutineScope, map -> { - Map> customRepositoriesMap = (Map>)map; - if (parser.suggested && project != null) { - List<@NotNull PluginUiModel> plugins = - PluginsAdvertiserStartupActivityKt.findSuggestedPlugins(project, customRepositoriesMap); - result.addModels(plugins); - updateSearchPanel(result, runQuery, plugins); - } - else if (!parser.repositories.isEmpty()) { - for (String repository : parser.repositories) { - List descriptors = customRepositoriesMap.get(repository); - if (descriptors == null) { - continue; - } - if (parser.searchQuery == null) { - result.addModels(descriptors); - } - else { - for (PluginUiModel descriptor : descriptors) { - if (StringUtil.containsIgnoreCase(descriptor.getName(), parser.searchQuery)) { - result.addModel(descriptor); - } - } - } - } - result.removeDuplicates(); - result.sortByName(); - updateSearchPanel(result, runQuery, result.getModels()); - } - else { - PluginModelAsyncOperationsExecutor.INSTANCE - .performMarketplaceSearch(myCoroutineScope, - parser.getUrlQuery(), - !result.getModels().isEmpty(), - (searchResult, updates) -> { - applySearchResult(result, searchResult, (List)updates, customRepositoriesMap, - parser, pluginToScore, searchIndex); - updatePanel(runQuery); - return null; - }); - } - return null; - }); - } - - private void updateSearchPanel(@NonNull PluginsGroup result, AtomicBoolean runQuery, List<@NotNull PluginUiModel> plugins) { - Set ids = plugins.stream().map(it -> it.getPluginId()).collect(Collectors.toSet()); - result.getPreloadedModel().setInstalledPlugins(UiPluginManager.getInstance().findInstalledPluginsSync(ids)); - result.getPreloadedModel().setPluginInstallationStates(UiPluginManager.getInstance().getInstallationStatesSync()); - updatePanel(runQuery); - } - - private void applySearchResult(@NotNull PluginsGroup result, - PluginSearchResult searchResult, - List updates, - Map> customRepositoriesMap, - SearchQueryParser.Marketplace parser, - Map pluginToScore, - int searchIndex) { - if (searchResult.getError() != null) { - ApplicationManager.getApplication().invokeLater( - () -> myPanel.getEmptyText() - .setText(IdeBundle.message("plugins.configurable.search.result.not.loaded")) - .appendSecondaryText( - IdeBundle.message("plugins.configurable.check.internet"), - StatusText.DEFAULT_ATTRIBUTES, null), ModalityState.any() - ); - } - // compare plugin versions between marketplace & custom repositories - List customPlugins = ContainerUtil.flatten(customRepositoriesMap.values()); - Collection plugins = - RepositoryHelper.mergePluginModelsFromRepositories(searchResult.getPlugins(), - customPlugins, - false); - result.addModels(0, new ArrayList<>(plugins)); - - if (parser.searchQuery != null) { - List descriptors = ContainerUtil.filter(customPlugins, - descriptor -> StringUtil.containsIgnoreCase( - descriptor.getName(), - parser.searchQuery)); - result.addModels(0, descriptors); - } - - result.removeDuplicates(); - - final var localRanker = MarketplaceLocalRanker.getInstanceIfEnabled(); - if (localRanker != null) { - pluginToScore = localRanker.rankPlugins(parser, result.getModels()); - } - - if (!result.getModels().isEmpty()) { - String title = IdeBundle.message("plugin.manager.action.label.sort.by.1"); - - for (AnAction action : myMarketplaceSortByGroup.getChildren(ActionManager.getInstance())) { - MarketplaceSortByAction sortByAction = (MarketplaceSortByAction)action; - sortByAction.setState(parser); - if (sortByAction.myState) { - title = IdeBundle.message("plugin.manager.action.label.sort.by", - sortByAction.myOption.getPresentableNameSupplier().get()); - } - } - - myMarketplaceSortByAction.setText(title); - result.addSecondaryAction(myMarketplaceSortByAction); - - if (!ContainerUtil.isEmpty(updates)) { - myPostFillGroupCallback = () -> { - applyUpdates(myPanel, updates); - selectionListener.accept(myMarketplacePanel); - selectionListener.accept(myMarketplaceSearchPanel.getPanel()); - }; - } - } - Set ids = result.getModels().stream().map(it -> it.getPluginId()).collect(Collectors.toSet()); - result.getPreloadedModel().setInstalledPlugins(UiPluginManager.getInstance().findInstalledPluginsSync(ids)); - result.getPreloadedModel().setPluginInstallationStates(UiPluginManager.getInstance().getInstallationStatesSync()); - PluginManagerUsageCollector.INSTANCE.performMarketplaceSearch(ProjectUtil.getActiveProject(), parser, result.getModels(), - searchIndex, pluginToScore); - } - }; + myMarketplaceSearchPanel = new MarketplaceSearchResultPanel(marketplaceController, panel, project, selectionListener); return myMarketplaceSearchPanel; } @@ -911,4 +755,173 @@ class MarketplacePluginsTab extends PluginsTab { return SearchWords.SORT_BY.getValue() + myOption.getQuery(); } } + + private class MarketplaceSearchResultPanel extends SearchResultPanel { + private final Project myProject; + private final @NotNull Consumer mySelectionListener; + + MarketplaceSearchResultPanel(SearchUpDownPopupController marketplaceController, + PluginsGroupComponentWithProgress panel, + Project project, + @NotNull Consumer selectionListener) { + super(MarketplacePluginsTab.this.myCoroutineScope, marketplaceController, panel, true); + myProject = project; + mySelectionListener = selectionListener; + } + + @Override + @SuppressWarnings("unchecked") + protected void handleQuery(@NotNull String query, @NotNull PluginsGroup result, AtomicBoolean runQuery) { + int searchIndex = PluginManagerUsageCollector.updateAndGetSearchIndex(); + + SearchQueryParser.Marketplace parser = new SearchQueryParser.Marketplace(query); + + Map pluginToScore = null; + + if (parser.internal) { + try { + PluginsViewCustomizer.PluginsGroupDescriptor groupDescriptor = + PluginsViewCustomizerKt.getPluginsViewCustomizer().getInternalPluginsGroupDescriptor(); + if (groupDescriptor != null) { + if (parser.searchQuery == null) { + result.addDescriptors(groupDescriptor.getPlugins()); + } + else { + for (IdeaPluginDescriptor pluginDescriptor : groupDescriptor.getPlugins()) { + if (StringUtil.containsIgnoreCase(pluginDescriptor.getName(), parser.searchQuery)) { + result.addDescriptor(pluginDescriptor); + } + } + } + result.removeDuplicates(); + result.sortByName(); + return; + } + } + catch (Exception e) { + LOG.error("Error while loading internal plugins group", e); + } + } + + PluginModelAsyncOperationsExecutor.INSTANCE.getCustomRepositoriesPluginMap(myCoroutineScope, map -> { + Map> customRepositoriesMap = (Map>)map; + if (parser.suggested && myProject != null) { + List<@NotNull PluginUiModel> plugins = + PluginsAdvertiserStartupActivityKt.findSuggestedPlugins(myProject, customRepositoriesMap); + result.addModels(plugins); + updateSearchPanel(result, runQuery, plugins); + } + else if (!parser.repositories.isEmpty()) { + for (String repository : parser.repositories) { + List descriptors = customRepositoriesMap.get(repository); + if (descriptors == null) { + continue; + } + if (parser.searchQuery == null) { + result.addModels(descriptors); + } + else { + for (PluginUiModel descriptor : descriptors) { + if (StringUtil.containsIgnoreCase(descriptor.getName(), parser.searchQuery)) { + result.addModel(descriptor); + } + } + } + } + result.removeDuplicates(); + result.sortByName(); + updateSearchPanel(result, runQuery, result.getModels()); + } + else { + PluginModelAsyncOperationsExecutor.INSTANCE + .performMarketplaceSearch(myCoroutineScope, + parser.getUrlQuery(), + !result.getModels().isEmpty(), + (searchResult, updates) -> { + applySearchResult(result, searchResult, (List)updates, customRepositoriesMap, + parser, pluginToScore, searchIndex); + updatePanel(runQuery); + return null; + }); + } + return null; + }); + } + + private void updateSearchPanel(@NonNull PluginsGroup result, AtomicBoolean runQuery, List<@NotNull PluginUiModel> plugins) { + Set ids = plugins.stream().map(it -> it.getPluginId()).collect(Collectors.toSet()); + result.getPreloadedModel().setInstalledPlugins(UiPluginManager.getInstance().findInstalledPluginsSync(ids)); + result.getPreloadedModel().setPluginInstallationStates(UiPluginManager.getInstance().getInstallationStatesSync()); + updatePanel(runQuery); + } + + private void applySearchResult(@NotNull PluginsGroup result, + PluginSearchResult searchResult, + List updates, + Map> customRepositoriesMap, + SearchQueryParser.Marketplace parser, + Map pluginToScore, + int searchIndex) { + if (searchResult.getError() != null) { + ApplicationManager.getApplication().invokeLater( + () -> myPanel.getEmptyText() + .setText(IdeBundle.message("plugins.configurable.search.result.not.loaded")) + .appendSecondaryText( + IdeBundle.message("plugins.configurable.check.internet"), + StatusText.DEFAULT_ATTRIBUTES, null), ModalityState.any() + ); + } + // compare plugin versions between marketplace & custom repositories + List customPlugins = ContainerUtil.flatten(customRepositoriesMap.values()); + Collection plugins = + RepositoryHelper.mergePluginModelsFromRepositories(searchResult.getPlugins(), + customPlugins, + false); + result.addModels(0, new ArrayList<>(plugins)); + + if (parser.searchQuery != null) { + List descriptors = ContainerUtil.filter(customPlugins, + descriptor -> StringUtil.containsIgnoreCase( + descriptor.getName(), + parser.searchQuery)); + result.addModels(0, descriptors); + } + + result.removeDuplicates(); + + final var localRanker = MarketplaceLocalRanker.getInstanceIfEnabled(); + if (localRanker != null) { + pluginToScore = localRanker.rankPlugins(parser, result.getModels()); + } + + if (!result.getModels().isEmpty()) { + String title = IdeBundle.message("plugin.manager.action.label.sort.by.1"); + + for (AnAction action : myMarketplaceSortByGroup.getChildren(ActionManager.getInstance())) { + MarketplaceSortByAction sortByAction = (MarketplaceSortByAction)action; + sortByAction.setState(parser); + if (sortByAction.myState) { + title = IdeBundle.message("plugin.manager.action.label.sort.by", + sortByAction.myOption.getPresentableNameSupplier().get()); + } + } + + myMarketplaceSortByAction.setText(title); + result.addSecondaryAction(myMarketplaceSortByAction); + + if (!ContainerUtil.isEmpty(updates)) { + myPostFillGroupCallback = () -> { + applyUpdates(myPanel, updates); + mySelectionListener.accept(myMarketplacePanel); + mySelectionListener.accept(myMarketplaceSearchPanel.getPanel()); + }; + } + } + Set ids = result.getModels().stream().map(it -> it.getPluginId()).collect(Collectors.toSet()); + result.getPreloadedModel().setInstalledPlugins(UiPluginManager.getInstance().findInstalledPluginsSync(ids)); + result.getPreloadedModel().setPluginInstallationStates(UiPluginManager.getInstance().getInstallationStatesSync()); + PluginManagerUsageCollector.INSTANCE.performMarketplaceSearch(ProjectUtil.getActiveProject(), parser, result.getModels(), + searchIndex, pluginToScore); + } + } } \ No newline at end of file