Skip to content
This repository has been archived by the owner on Apr 9, 2021. It is now read-only.

Commit

Permalink
Improve display of member search results
Browse files Browse the repository at this point in the history
Align them, escape nicks, show ids
  • Loading branch information
schnapster committed Jan 27, 2018
1 parent bd81c61 commit 5700ad9
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

import javax.annotation.Nonnull;
import java.util.List;
import java.util.stream.Collectors;

public class FuzzyUserSearchCommand extends Command implements IInfoCommand {

Expand All @@ -56,40 +55,9 @@ public void onInvoke(@Nonnull CommandContext context) {
return;
}

int idPadding = list.stream()
.mapToInt(member -> member.getUser().getId().length())
.max()
.orElse(0);
int namePadding = list.stream()
.mapToInt(member -> member.getUser().getName().length())
.max()
.orElse(0);
int nickPadding = list.stream()
.mapToInt(member -> member.getNickname() != null ? member.getNickname().length() : 0)
.max()
.orElse(0);

List<String> lines = list.stream()
.map(member -> TextUtils.padWithSpaces(member.getUser().getId(), idPadding, true)
+ " " + TextUtils.padWithSpaces(member.getUser().getName(), namePadding, false)
+ " " + TextUtils.padWithSpaces(member.getNickname(), nickPadding, false)
+ "\n")
.collect(Collectors.toList());


StringBuilder sb = new StringBuilder(TextUtils.padWithSpaces("Id", idPadding + 1, false)
+ TextUtils.padWithSpaces("Name", namePadding + 1, false)
+ TextUtils.padWithSpaces("Nick", nickPadding + 1, false) + "\n");

for (String line : lines) {
if (sb.length() + line.length() + query.length() < 1900) { //respect max message size
sb.append(line);
} else {
sb.append("[...]");
break;
}
}
context.replyWithName("Results for `" + query + "`: " + TextUtils.asCodeBlock(sb.toString()));
String escapedQuery = TextUtils.escapeAndDefuse(query);
String formatted = ArgumentUtil.formatFuzzyMemberResult(list, Integer.MAX_VALUE, 1900 - escapedQuery.length());
context.replyWithName("Results for `" + escapedQuery + "`:\n" + formatted);
}
}

Expand Down
80 changes: 66 additions & 14 deletions FredBoat/src/main/java/fredboat/util/ArgumentUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class ArgumentUtil {

Expand Down Expand Up @@ -90,25 +91,76 @@ public static Member checkSingleFuzzyMemberSearchResult(CommandContext context,
case 1:
return list.get(0);
default:
StringBuilder searchResults = new StringBuilder();
int maxIndex = Math.min(FUZZY_RESULT_LIMIT, list.size());
for (int i = 0; i < maxIndex; i++) {
searchResults.append("\n")
.append(list.get(i).getUser().getName())
.append("#")
.append(list.get(i).getUser().getDiscriminator());
}

if (list.size() > FUZZY_RESULT_LIMIT) {
searchResults.append("\n[...]");
}

context.reply(context.i18n("fuzzyMultiple") + "\n"
+ TextUtils.asCodeBlock(searchResults.toString()));
+ formatFuzzyMemberResult(list, FUZZY_RESULT_LIMIT, 1900));
return null;
}
}

/**
* Format a list of members as a text block, usually a result from a fuzzy search. The list should not be empty.
*
* @param maxLines How many results to display. Pass Integer.MAX_VALUE to use as many as possible.
* @param maxLength How many characters the resulting string may have as a max.
*/
@Nonnull
public static String formatFuzzyMemberResult(@Nonnull List<Member> list, int maxLines, int maxLength) {

List<Member> toDisplay;
boolean addDots = false;
if (list.size() > maxLines) {
addDots = true;
toDisplay = list.subList(0, maxLines);
} else {
toDisplay = new ArrayList<>(list);
}

int idPadding = toDisplay.stream()
.mapToInt(member -> member.getUser().getId().length())
.max()
.orElse(0);
int namePadding = toDisplay.stream()
.mapToInt(member -> TextUtils.escapeBackticks(member.getUser().getName()).length())
.max()
.orElse(0)
+ 5;//for displaying discrim
int nickPadding = toDisplay.stream()
.mapToInt(member -> member.getNickname() != null ? TextUtils.escapeBackticks(member.getNickname()).length() : 0)
.max()
.orElse(0);

List<String> lines = toDisplay.stream()
.map(member -> TextUtils.padWithSpaces(member.getUser().getId(), idPadding, true)
+ " " + TextUtils.padWithSpaces(TextUtils.escapeBackticks(member.getUser().getName())
+ "#" + member.getUser().getDiscriminator(), namePadding, false)
+ " " + TextUtils.escapeBackticks(TextUtils.padWithSpaces(member.getNickname(), nickPadding, false))
+ "\n")
.collect(Collectors.toList());


StringBuilder sb = new StringBuilder(TextUtils.padWithSpaces("Id", idPadding + 1, false)
+ TextUtils.padWithSpaces("Name", namePadding + 1, false)
+ TextUtils.padWithSpaces("Nick", nickPadding + 1, false) + "\n");

int textBlockLength = 8;
String dotdotdot = "[...]";
for (int i = 0; i < toDisplay.size(); i++) {
String line = lines.get(i);
if (sb.length() + line.length() + dotdotdot.length() + textBlockLength < maxLength) {
sb.append(line);
} else {
sb.append(dotdotdot);
addDots = false; //already added
break;
}
}
if (addDots) {
sb.append(dotdotdot);
}

return TextUtils.asCodeBlock(sb.toString());
}

/**
* Processes a list of mentionables (roles / users).
* Replies in the context of there are none / more than one mentionable and returns null, otherwise returns the
Expand Down
24 changes: 15 additions & 9 deletions FredBoat/src/main/java/fredboat/util/TextUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand All @@ -64,7 +61,8 @@ public class TextUtils {

private static final Pattern TIMESTAMP_PATTERN = Pattern.compile("^(\\d?\\d)(?::([0-5]?\\d))?(?::([0-5]?\\d))?$");

private static final List<Character> markdownChars = Arrays.asList('*', '`', '~', '_');
private static final Collection<Character> BACKTICK = Collections.singleton('`');
private static final List<Character> MARKDOWN_CHARS = Arrays.asList('*', '`', '~', '_');

public static final CharMatcher SPLIT_SELECT_SEPARATOR =
CharMatcher.whitespace().or(CharMatcher.is(','))
Expand Down Expand Up @@ -272,17 +270,25 @@ public static String asCodeBlock(String str, String... style) {
return "```" + sty + "\n" + str + "\n```";
}

public static String escapeMarkdown(String str) {
StringBuilder revisedString = new StringBuilder(str.length());
for (Character n : str.toCharArray()) {
if (markdownChars.contains(n)) {
public static String escape(@Nonnull String input, @Nonnull Collection<Character> toEscape) {
StringBuilder revisedString = new StringBuilder(input.length());
for (Character n : input.toCharArray()) {
if (toEscape.contains(n)) {
revisedString.append("\\");
}
revisedString.append(n);
}
return revisedString.toString();
}

public static String escapeMarkdown(@Nonnull String input) {
return escape(input, MARKDOWN_CHARS);
}

public static String escapeBackticks(@Nonnull String input) {
return escape(input, BACKTICK);
}


public static String forceNDigits(int i, int n) {
String str = Integer.toString(i);
Expand Down

0 comments on commit 5700ad9

Please sign in to comment.