From 98aa9fb7d79e48169b39472c8115ad21dec303d4 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 27 Feb 2020 05:28:07 +0100 Subject: [PATCH 1/3] Move matchesSearchTerms util to Text class Signed-off-by: Tomas Slusny --- .../ExternalPluginManifest.java | 3 +++ .../client/plugins/config/PluginListItem.java | 22 +------------------ .../plugins/config/PluginListPanel.java | 2 +- .../java/net/runelite/client/util/Text.java | 20 +++++++++++++++++ 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginManifest.java b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginManifest.java index 95b5fe5637..0678bf768c 100644 --- a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginManifest.java +++ b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginManifest.java @@ -29,6 +29,7 @@ import com.google.common.io.Files; import java.io.File; import java.io.IOException; import java.net.URL; +import javax.annotation.Nullable; import lombok.Data; import lombok.EqualsAndHashCode; import net.runelite.client.RuneLite; @@ -45,7 +46,9 @@ public class ExternalPluginManifest private String displayName; private String version; private String author; + @Nullable private String description; + @Nullable private String[] tags; @EqualsAndHashCode.Exclude private URL support; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java index 9b1575acc3..2c5cfe5bbd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java @@ -52,12 +52,9 @@ import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.SwingUtil; -import org.apache.commons.text.similarity.JaroWinklerDistance; class PluginListItem extends JPanel { - private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance(); - private static final ImageIcon CONFIG_ICON; private static final ImageIcon CONFIG_ICON_HOVER; private static final ImageIcon ON_STAR; @@ -68,6 +65,7 @@ class PluginListItem extends JPanel @Getter private final PluginConfigurationDescriptor pluginConfig; + @Getter private final List keywords = new ArrayList<>(); private final JToggleButton pinButton; @@ -202,24 +200,6 @@ class PluginListItem extends JPanel onOffToggle.setSelected(enabled); } - /** - * Checks if all the search terms in the given list matches at least one keyword. - * - * @return true if all search terms matches at least one keyword, or false if otherwise. - */ - boolean matchesSearchTerms(String[] searchTerms) - { - for (String term : searchTerms) - { - if (keywords.stream().noneMatch((t) -> t.contains(term) || - DISTANCE.apply(t, term) > 0.9)) - { - return false; - } - } - return true; - } - private void openGroupConfigPanel() { pluginListPanel.openConfigurationPanel(pluginConfig); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java index 2e96a4dae9..57ac970cae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java @@ -271,7 +271,7 @@ class PluginListPanel extends PluginPanel final String[] searchTerms = text.toLowerCase().split(" "); pluginList.forEach(listItem -> { - if (pinned == listItem.isPinned() && listItem.matchesSearchTerms(searchTerms)) + if (pinned == listItem.isPinned() && Text.matchesSearchTerms(searchTerms, listItem.getKeywords())) { mainPanel.add(listItem); } diff --git a/runelite-client/src/main/java/net/runelite/client/util/Text.java b/runelite-client/src/main/java/net/runelite/client/util/Text.java index 78c08f16aa..6fc303a97e 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/Text.java +++ b/runelite-client/src/main/java/net/runelite/client/util/Text.java @@ -32,12 +32,14 @@ import java.util.Collection; import java.util.List; import java.util.regex.Pattern; import org.apache.commons.text.WordUtils; +import org.apache.commons.text.similarity.JaroWinklerDistance; /** * A set of utilities to use when dealing with text. */ public class Text { + private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance(); private static final Pattern TAG_REGEXP = Pattern.compile("<[^>]*>"); private static final Splitter COMMA_SPLITTER = Splitter .on(",") @@ -186,4 +188,22 @@ public class Text return toString; } + + /** + * Checks if all the search terms in the given list matches at least one keyword. + * + * @return true if all search terms matches at least one keyword, or false if otherwise. + */ + public static boolean matchesSearchTerms(String[] searchTerms, final Collection keywords) + { + for (String term : searchTerms) + { + if (keywords.stream().noneMatch((t) -> t.contains(term) || + DISTANCE.apply(t, term) > 0.9)) + { + return false; + } + } + return true; + } } From fdd75b1296df120848c39cccd7b6bcf635fde852 Mon Sep 17 00:00:00 2001 From: loldudester Date: Thu, 27 Feb 2020 04:08:39 +0000 Subject: [PATCH 2/3] Plugin Hub: Sort plugins by display name --- .../java/net/runelite/client/plugins/config/PluginHubPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java index 169f061d17..a94c94a592 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java @@ -543,7 +543,7 @@ class PluginHubPanel extends PluginPanel else { stream = stream - .sorted(Comparator.comparing(PluginItem::isInstalled)); + .sorted(Comparator.comparing(PluginItem::isInstalled).thenComparing(p -> p.manifest.getDisplayName())); } stream.forEach(mainPanel::add); From dcc2c577bdf61c9b87a9ea815eefe57f13afbd16 Mon Sep 17 00:00:00 2001 From: loldudester Date: Thu, 27 Feb 2020 01:49:17 +0000 Subject: [PATCH 3/3] Plugin Hub: Rework search to something remotely useful --- .../client/plugins/config/PluginHubPanel.java | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java index a94c94a592..269cfe574f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java @@ -37,7 +37,9 @@ import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; @@ -45,7 +47,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import java.util.function.Function; -import java.util.function.ToDoubleFunction; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -85,8 +86,8 @@ import net.runelite.client.ui.components.IconTextField; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.SwingUtil; +import net.runelite.client.util.Text; import net.runelite.client.util.VerificationException; -import org.apache.commons.text.similarity.JaroWinklerDistance; @Slf4j @Singleton @@ -98,7 +99,6 @@ class PluginHubPanel extends PluginPanel private static final ImageIcon CONFIGURE_ICON; private static final ImageIcon CONFIGURE_ICON_HOVER; private static final Pattern SPACES = Pattern.compile(" +"); - private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance(); static { @@ -119,16 +119,13 @@ class PluginHubPanel extends PluginPanel private static final int HEIGHT = 70; private static final int ICON_WIDTH = 48; private static final int BOTTOM_LINE_HEIGHT = 16; - static final float MIN_FILTER_SCORE = .8f; private final ExternalPluginManifest manifest; + private final List keywords = new ArrayList<>(); @Getter private final boolean installed; - @Getter - private float filter; - PluginItem(ExternalPluginManifest newManifest, Collection loadedPlugins, boolean installed) { ExternalPluginManifest loaded = null; @@ -140,6 +137,23 @@ class PluginHubPanel extends PluginPanel manifest = newManifest == null ? loaded : newManifest; this.installed = installed; + if (manifest != null) + { + Collections.addAll(keywords, SPACES.split(manifest.getDisplayName().toLowerCase())); + + if (manifest.getDescription() != null) + { + Collections.addAll(keywords, SPACES.split(manifest.getDescription().toLowerCase())); + } + + Collections.addAll(keywords, manifest.getAuthor().toLowerCase()); + + if (manifest.getTags() != null) + { + Collections.addAll(keywords, manifest.getTags()); + } + } + setBackground(ColorScheme.DARKER_GRAY_COLOR); setOpaque(true); @@ -302,23 +316,6 @@ class PluginHubPanel extends PluginPanel .addComponent(addrm, BOTTOM_LINE_HEIGHT, BOTTOM_LINE_HEIGHT, BOTTOM_LINE_HEIGHT)) .addGap(5))); } - - float setFilter(String[] filter) - { - ToDoubleFunction match = r -> Stream.of(filter) - .mapToDouble(l -> Math.pow(DISTANCE.apply(l, r), 2)) - .max() - .orElse(0.D); - - double sim = SPACES.splitAsStream(manifest.getDisplayName()).collect(Collectors.averagingDouble(match)) * 2; - - if (manifest.getTags() != null) - { - sim += Stream.of(manifest.getTags()).mapToDouble(match).sum(); - } - - return this.filter = (float) sim; - } } private final PluginListPanel pluginListPanel; @@ -537,8 +534,8 @@ class PluginHubPanel extends PluginPanel { String[] searchArray = SPACES.split(search.toLowerCase()); stream = stream - .filter(p -> p.setFilter(searchArray) > PluginItem.MIN_FILTER_SCORE) - .sorted(Comparator.comparing(PluginItem::getFilter)); + .filter(p -> Text.matchesSearchTerms(searchArray, p.keywords)) + .sorted(Comparator.comparing(p -> p.manifest.getDisplayName())); } else {