From 4bfd2668e40d01c3f693d299f7fc85722848024d Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Thu, 20 Dec 2018 19:32:58 +0300 Subject: [PATCH] Load and show plugin logo icon: group bg requests --- .../plugins/PluginManagerConfigurableNew.java | 9 +- .../ide/plugins/newui/PluginLogo.java | 196 +++++++++++------- .../plugins/newui/PluginsGroupComponent.java | 2 + .../ide/plugins/newui/SearchResultPanel.java | 2 + 4 files changed, 132 insertions(+), 77 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNew.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNew.java index 9469f090d885..02e0e5c348b5 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNew.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNew.java @@ -801,11 +801,13 @@ public class PluginManagerConfigurableNew finally { ApplicationManager.getApplication().invokeLater(() -> { myTrendingPanel.stopLoading(); + PluginLogo.startBatchMode(); for (PluginsGroup group : groups) { myTrendingPanel.addGroup(group); } + PluginLogo.endBatchMode(); myTrendingPanel.doLayout(); myTrendingPanel.initialSelection(); }, ModalityState.any()); @@ -832,6 +834,7 @@ public class PluginManagerConfigurableNew new PluginsGroupComponent(new PluginsListLayout(), new MultiSelectionEventHandler(), myNameListener, mySearchListener, descriptor -> new ListPluginComponent(myPluginsModel, descriptor, false)); registerCopyProvider(panel); + PluginLogo.startBatchMode(); PluginsGroup installing = new PluginsGroup("Installing"); installing.descriptors.addAll(MyPluginModel.getInstallingPlugins()); @@ -905,6 +908,7 @@ public class PluginManagerConfigurableNew } }); + PluginLogo.endBatchMode(); return createScrollPane(panel, true); } @@ -953,9 +957,11 @@ public class PluginManagerConfigurableNew group.descriptors.add(toUpdateDownloader.getDescriptor()); } + PluginLogo.startBatchMode(); group.sortByName(); myUpdatesPanel.addGroup(group); group.titleWithCount(); + PluginLogo.endBatchMode(); myPluginsModel.setUpdateGroup(group); } @@ -1492,7 +1498,8 @@ public class PluginManagerConfigurableNew } public static boolean forceHttps() { - return IdeaApplication.isLoaded() && UpdateSettings.getInstance().canUseSecureConnection(); + return IdeaApplication.isLoaded() && !ApplicationManager.getApplication().isDisposed() && + UpdateSettings.getInstance().canUseSecureConnection(); } @NotNull diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginLogo.java b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginLogo.java index e50fe7b07fa2..1edd85071b52 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginLogo.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginLogo.java @@ -6,10 +6,7 @@ import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManagerConfigurableNew; import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.ide.ui.LafManager; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.JetBrainsProtocolHandler; -import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.*; import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.IconLoader; @@ -31,9 +28,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -49,6 +44,7 @@ public class PluginLogo { private static final Map> ICONS = new HashMap<>(); private static PluginLogoIconProvider Default; + private static List> myPrepareToLoad; static { LafManager.getInstance().addLafManagerListener(_0 -> Default = null); @@ -68,6 +64,18 @@ public class PluginLogo { return getDefault(); } + public static void startBatchMode() { + assert myPrepareToLoad == null; + myPrepareToLoad = new ArrayList<>(); + } + + public static void endBatchMode() { + assert myPrepareToLoad != null; + List> descriptors = myPrepareToLoad; + myPrepareToLoad = null; + runLoadTask(descriptors); + } + @NotNull private static PluginLogoIconProvider getDefault() { if (Default == null) { @@ -90,76 +98,102 @@ public class PluginLogo { Pair lazyIcons = Pair.create(lazyIcon, lazyIcon); ICONS.put(idPlugin, lazyIcons); - ApplicationManager.getApplication().executeOnPooledThread(() -> { - File path = descriptor.getPath(); - if (path != null) { - if (path.isDirectory()) { - if (System.getProperty(JetBrainsProtocolHandler.REQUIRED_PLUGINS_KEY) != null) { - if (tryLoadDirIcons(idPlugin, lazyIcon, new File(path, "classes"))) { - return; - } - } + Pair info = Pair.create(descriptor, lazyIcon); - if (tryLoadDirIcons(idPlugin, lazyIcon, path)) { - return; - } - - File libFile = new File(path, "lib"); - if (!libFile.exists() || !libFile.isDirectory()) { - return; - } - - File[] files = libFile.listFiles(); - if (files == null || files.length == 0) { - return; - } - - for (File file : files) { - if (tryLoadDirIcons(idPlugin, lazyIcon, file)) { - return; - } - if (tryLoadJarIcons(idPlugin, lazyIcon, file, false)) { - return; - } - } - } - else { - tryLoadJarIcons(idPlugin, lazyIcon, path, true); - } - return; - } - - String idFileName = FileUtil.sanitizeFileName(idPlugin); - File cache = new File(PathManager.getPluginTempPath(), CACHE_DIR); - File lightFile = new File(cache, idFileName + ".svg"); - File darkFile = new File(cache, idFileName + "_dark.svg"); - - if (cache.exists()) { - PluginLogoIconProvider light = tryLoadIcon(lightFile); - PluginLogoIconProvider dark = tryLoadIcon(darkFile); - if (light != null || dark != null) { - putIcon(idPlugin, lazyIcon, light, dark); - return; - } - } - - try { - FileUtil.createParentDirs(cache); - downloadFile(idPlugin, lightFile, ""); - downloadFile(idPlugin, darkFile, "&theme=DARCULA"); - } - catch (Exception e) { - LOG.error(e); - } - - PluginLogoIconProvider light = tryLoadIcon(lightFile); - PluginLogoIconProvider dark = tryLoadIcon(darkFile); - putIcon(idPlugin, lazyIcon, light, dark); - }); + if (myPrepareToLoad == null) { + runLoadTask(Collections.singletonList(info)); + } + else { + myPrepareToLoad.add(info); + } return lazyIcons; } + private static void runLoadTask(@NotNull List> loadInfo) { + Application application = ApplicationManager.getApplication(); + application.executeOnPooledThread(() -> { + for (Pair info : loadInfo) { + if (application.isDisposed()) { + return; + } + loadPluginIcons(info.first, info.second); + } + }); + } + + private static void loadPluginIcons(@NotNull IdeaPluginDescriptor descriptor, @NotNull LazyPluginLogoIcon lazyIcon) { + String idPlugin = descriptor.getPluginId().getIdString(); + File path = descriptor.getPath(); + + if (path != null) { + if (path.isDirectory()) { + if (System.getProperty(JetBrainsProtocolHandler.REQUIRED_PLUGINS_KEY) != null) { + if (tryLoadDirIcons(idPlugin, lazyIcon, new File(path, "classes"))) { + return; + } + } + + if (tryLoadDirIcons(idPlugin, lazyIcon, path)) { + return; + } + + File libFile = new File(path, "lib"); + if (!libFile.exists() || !libFile.isDirectory()) { + return; + } + + File[] files = libFile.listFiles(); + if (files == null || files.length == 0) { + return; + } + + for (File file : files) { + if (tryLoadDirIcons(idPlugin, lazyIcon, file)) { + return; + } + if (tryLoadJarIcons(idPlugin, lazyIcon, file, false)) { + return; + } + } + } + else { + tryLoadJarIcons(idPlugin, lazyIcon, path, true); + } + return; + } + + String idFileName = FileUtil.sanitizeFileName(idPlugin); + File cache = new File(PathManager.getPluginTempPath(), CACHE_DIR); + File lightFile = new File(cache, idFileName + ".svg"); + File darkFile = new File(cache, idFileName + "_dark.svg"); + + if (cache.exists()) { + PluginLogoIconProvider light = tryLoadIcon(lightFile); + PluginLogoIconProvider dark = tryLoadIcon(darkFile); + if (light != null || dark != null) { + putIcon(idPlugin, lazyIcon, light, dark); + return; + } + } + + try { + downloadFile(idPlugin, lightFile, ""); + downloadFile(idPlugin, darkFile, "&theme=DARCULA"); + } + catch (Exception e) { + LOG.error(e); + } + + if (ApplicationManager.getApplication().isDisposed()) { + return; + } + + PluginLogoIconProvider light = tryLoadIcon(lightFile); + PluginLogoIconProvider dark = tryLoadIcon(darkFile); + putIcon(idPlugin, lazyIcon, light, dark); + } + private static boolean tryLoadDirIcons(@NotNull String idPlugin, @NotNull LazyPluginLogoIcon lazyIcon, @NotNull File path) { PluginLogoIconProvider light = tryLoadIcon(new File(path, PluginManagerCore.META_INF + PLUGIN_ICON)); PluginLogoIconProvider dark = tryLoadIcon(new File(path, PluginManagerCore.META_INF + PLUGIN_ICON_DARK)); @@ -194,15 +228,25 @@ public class PluginLogo { } private static void downloadFile(@NotNull String idPlugin, @NotNull File file, @NotNull String theme) { + if (ApplicationManager.getApplication().isDisposed()) { + return; + } + try { Url url = Urls.newFromEncoded(ApplicationInfoImpl.getShadowInstance().getPluginManagerUrl() + "/api/icon?pluginId=" + URLUtil.encodeURIComponent(idPlugin) + theme); - HttpRequests.request(url).forceHttps(PluginManagerConfigurableNew.forceHttps()).throwStatusCodeException(false) - .productNameAsUserAgent().saveToFile(file, null); + HttpRequests.request(url).forceHttps(PluginManagerConfigurableNew.forceHttps()).productNameAsUserAgent() + .connect(request -> { + request.getConnection(); + request.saveToFile(file, null); + return null; + }); + } + catch (HttpRequests.HttpStatusException ignore) { } catch (IOException e) { - LOG.debug(e); + LOG.error(e); } } @@ -225,7 +269,7 @@ public class PluginLogo { @Nullable private static PluginLogoIconProvider tryLoadIcon(@NotNull File iconFile) { //noinspection IOResourceOpenedButNotSafelyClosed - return iconFile.exists() ? loadFileIcon(() -> new FileInputStream(iconFile)) : null; + return iconFile.exists() && iconFile.length() > 0 ? loadFileIcon(() -> new FileInputStream(iconFile)) : null; } @Nullable diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginsGroupComponent.java b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginsGroupComponent.java index 7df17ff3dec3..00cce9250bce 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginsGroupComponent.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginsGroupComponent.java @@ -85,7 +85,9 @@ public class PluginsGroupComponent extends JBPanelWithEmptyText { int fromIndex = group.ui.plugins.size(); int toIndex = Math.min(fromIndex + gapSize, group.descriptors.size()); int uiIndex = getComponentIndex(group.ui.plugins.get(fromIndex - 1)); + PluginLogo.startBatchMode(); addToGroup(group, group.descriptors.subList(fromIndex, toIndex), uiIndex); + PluginLogo.endBatchMode(); if (group.descriptors.size() == group.ui.plugins.size()) { scrollBar.removeAdjustmentListener(this); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/SearchResultPanel.java b/platform/platform-impl/src/com/intellij/ide/plugins/newui/SearchResultPanel.java index cc7c49a5df4f..d9ac79076baf 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/SearchResultPanel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/SearchResultPanel.java @@ -113,7 +113,9 @@ public abstract class SearchResultPanel { if (!myGroup.descriptors.isEmpty()) { myGroup.titleWithCount(); + PluginLogo.startBatchMode(); myPanel.addLazyGroup(myGroup, myVerticalScrollBar, 100, this::fullRepaint); + PluginLogo.endBatchMode(); } myPanel.initialSelection(false);