mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Add creator= and artist= filters
To match stable, add creator= and artist= filters to the beatmap carousel on song select screen. Contrary to stable, this implementation supports phrase queries with spaces within using double quotes. The quote handling is not entirely correct (can't nest), but quotes should rarely happen within names, and it is an edge case of an edge case - leaving best-effort as is. Test coverage also included.
This commit is contained in:
@ -39,6 +39,10 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
match &= criteria.BeatDivisor.IsInRange(Beatmap.BeatDivisor);
|
||||
match &= criteria.OnlineStatus.IsInRange(Beatmap.Status);
|
||||
|
||||
match &= criteria.Creator.Matches(Beatmap.Metadata.AuthorString);
|
||||
match &= criteria.Artist.Matches(Beatmap.Metadata.Artist) ||
|
||||
criteria.Artist.Matches(Beatmap.Metadata.ArtistUnicode);
|
||||
|
||||
if (match)
|
||||
foreach (var criteriaTerm in criteria.SearchTerms)
|
||||
match &=
|
||||
|
@ -23,6 +23,8 @@ namespace osu.Game.Screens.Select
|
||||
public OptionalRange<double> BPM;
|
||||
public OptionalRange<int> BeatDivisor;
|
||||
public OptionalRange<BeatmapSetOnlineStatus> OnlineStatus;
|
||||
public OptionalTextFilter Creator;
|
||||
public OptionalTextFilter Artist;
|
||||
|
||||
public string[] SearchTerms = Array.Empty<string>();
|
||||
|
||||
@ -82,5 +84,24 @@ namespace osu.Game.Screens.Select
|
||||
&& IsLowerInclusive.Equals(other.IsLowerInclusive)
|
||||
&& IsUpperInclusive.Equals(other.IsUpperInclusive);
|
||||
}
|
||||
|
||||
public struct OptionalTextFilter : IEquatable<OptionalTextFilter>
|
||||
{
|
||||
public bool Matches(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SearchTerm))
|
||||
return true;
|
||||
|
||||
// search term is guaranteed to be non-empty, so if the string we're comparing is empty, it's not matching
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return false;
|
||||
|
||||
return value.IndexOf(SearchTerm, StringComparison.InvariantCultureIgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
public string SearchTerm;
|
||||
|
||||
public bool Equals(OptionalTextFilter other) => SearchTerm?.Equals(other.SearchTerm) ?? true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace osu.Game.Screens.Select
|
||||
internal static class FilterQueryParser
|
||||
{
|
||||
private static readonly Regex query_syntax_regex = new Regex(
|
||||
@"\b(?<key>stars|ar|dr|cs|divisor|length|objects|bpm|status)(?<op>[=:><]+)(?<value>\S*)",
|
||||
@"\b(?<key>stars|ar|dr|cs|divisor|length|objects|bpm|status|creator|artist)(?<op>[=:><]+)(?<value>("".*"")|(\S*))",
|
||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
internal static void ApplyQueries(FilterCriteria criteria, string query)
|
||||
@ -61,6 +61,14 @@ namespace osu.Game.Screens.Select
|
||||
case "status" when Enum.TryParse<BeatmapSetOnlineStatus>(value, true, out var statusValue):
|
||||
updateCriteriaRange(ref criteria.OnlineStatus, op, statusValue);
|
||||
break;
|
||||
|
||||
case "creator":
|
||||
updateCriteriaText(ref criteria.Creator, op, value);
|
||||
break;
|
||||
|
||||
case "artist":
|
||||
updateCriteriaText(ref criteria.Artist, op, value);
|
||||
break;
|
||||
}
|
||||
|
||||
query = query.Replace(match.ToString(), "");
|
||||
@ -78,6 +86,17 @@ namespace osu.Game.Screens.Select
|
||||
private static bool parseInt(string value, out int result) =>
|
||||
int.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result);
|
||||
|
||||
private static void updateCriteriaText(ref FilterCriteria.OptionalTextFilter textFilter, string op, string value)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case "=":
|
||||
case ":":
|
||||
textFilter.SearchTerm = value.Trim('"');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateCriteriaRange(ref FilterCriteria.OptionalRange<float> range, string op, float value, float tolerance = 0.05f)
|
||||
{
|
||||
updateCriteriaRange(ref range, op, value);
|
||||
|
Reference in New Issue
Block a user