mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-07-24 03:56:30 +00:00
794afa6c2c
* Migrate to Fluent UI * Setup window events for Blazor WebView * Setup basic FluentUI styling * FluentUI links * Setup views and viewmodel infra * Remove old navigation logic * Prepare an example of iframe embed * Style window + navigation menu * Setup page based navigation * Add some UI error handling * Introduce UI resiliency to exceptions * Setup settings menu dropdown * Basic setup for options views * Setup reusable OptionBase * Setup options views * Basic styling * Setup scoped css files. Split App into components * Hook option updates to OptionProvider * Fix option dropdowns * Setup multiple themes * Make fonts scalable * Move ViewModels under Views * Launch view + styling * Setup FocusView base * Finish BuildListView implementation * Base for build views * Setup build routing * Implement single build editor * Implement skill description on hover * Scrape skill information from the wiki and cache it locally * Scrape and fix Guild Wars wiki info * Improve mouse hover performance by querying position only when needed * Skill snippet snaps to edges * Setup accounts and executables view * Launch configurations view * Fix build skill icons Attach skill types to skills Scrape upkeep from wiki * Fix skilltype overflow * Adjust navigation menu * Setup privilege elevation flow * Setup MSAL * Options synchronization view * Telemetry view * Version management and update view * Setup plugins view * Setup notifications panel * Base for logs view * Finish LogView * Setup metrics view * Setup UI logging interop * GuildWarsPartySearch view implementation * Setup gitlab mirror job * Eventviewer base * Remove gitlab mirror * Remove mirror pipeline * Fix metricsview crashes * Extract progress component * Setup trade chat views * Setup Download view * Extract progress styling * Setup guild wars copy view * Setup trade alerts * Fix team template view skill selection * Setup basic onboarding view * Overhaul asynchronous progress operations and remove redundant versioning code * Setup modsview base * Setup modsview with mod states * Setup mod installation process * Cleanup more ui migration Remove price history #1076 * Screen selector manage view * Upgrade to .net 10 Closes #1078 * gMod management view * Trader message notification * ReShade management * Update for toolbox * Setup focusview fetching * Setup CharacterComponent * Setup vanquishing component * Setup TitleInformationComponent * Closes #1082 Fix API project for Guild Wars Reforged * Small fixes + attempts to get new exe version * FileId fixes * Current Map and Player Resources widgets * Quest log widget * BuildComponent implementation * Closes #1075 Embed wwwroot into the executable * Cleanup * Fixes to slnx * Fix test project
86 lines
3.1 KiB
C#
86 lines
3.1 KiB
C#
using System.Extensions;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Daybreak.Shared.Utils;
|
|
|
|
public static partial class StringUtils
|
|
{
|
|
private const double SimilarityThreshold = 0.8;
|
|
private static readonly Regex SplitIntoWordsRegex = WordRegex();
|
|
|
|
public static int DamerauLevenshteinDistance(string s, string t)
|
|
{
|
|
var (height, width) = (s.Length + 1, t.Length + 1);
|
|
|
|
var matrix = new int[height, width];
|
|
|
|
for (var j = 0; j < height; j++) { matrix[j, 0] = j; };
|
|
for (var i = 0; i < width; i++) { matrix[0, i] = i; };
|
|
|
|
for (var j = 1; j < height; j++)
|
|
{
|
|
for (var i = 1; i < width; i++)
|
|
{
|
|
var cost = s[j - 1] == t[i - 1] ? 0 : 1;
|
|
var insertion = matrix[j, i - 1] + 1;
|
|
var deletion = matrix[j - 1, i] + 1;
|
|
var substitution = matrix[j - 1, i - 1] + cost;
|
|
|
|
var distance = Math.Min(insertion, Math.Min(deletion, substitution));
|
|
|
|
if (j > 1 && i > 1 && s[j - 1] == t[i - 2] && s[j - 2] == t[i - 1])
|
|
{
|
|
distance = Math.Min(distance, matrix[j - 2, i - 2] + cost);
|
|
}
|
|
|
|
matrix[j, i] = distance;
|
|
}
|
|
}
|
|
|
|
return matrix[height - 1, width - 1];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if stringToSearch is somewhat close to searchString.
|
|
/// </summary>
|
|
/// <param name="stringToSearch"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>True if strings match.</returns>
|
|
public static bool MatchesSearchString(string stringToSearch, string searchString, double threshold = SimilarityThreshold)
|
|
{
|
|
if (stringToSearch.IsNullOrWhiteSpace() ||
|
|
searchString.IsNullOrWhiteSpace())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (stringToSearch.Length > searchString.Length
|
|
? stringToSearch.Contains(searchString, StringComparison.OrdinalIgnoreCase)
|
|
: searchString.Contains(stringToSearch, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
var distance = MatchSearchStringScore(stringToSearch, searchString);
|
|
var similarity = 1.0 - ((double)distance / searchString.Length);
|
|
return similarity >= threshold;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the match string score
|
|
/// </summary>
|
|
/// <param name="stringToSearch"></param>
|
|
/// <param name="searchString"></param>
|
|
/// <returns>True if strings match.</returns>
|
|
public static int MatchSearchStringScore(string stringToSearch, string searchString)
|
|
{
|
|
return Math.Min(
|
|
DamerauLevenshteinDistance(stringToSearch.ToLower()[..Math.Min(stringToSearch.Length, searchString.Length)], searchString.ToLower()),
|
|
SplitIntoWordsRegex.Split(stringToSearch.ToLower())
|
|
.Select(word => DamerauLevenshteinDistance(word.ToLower()[..Math.Min(word.Length, searchString.Length)], searchString.ToLower())).Min());
|
|
}
|
|
|
|
[GeneratedRegex(@"\W+", RegexOptions.Compiled)]
|
|
private static partial Regex WordRegex();
|
|
}
|