using System; using System.Collections.Generic; using System.Globalization; using System.Threading; namespace Nitrox.Launcher.Models.Converters; /// /// Trims the value when retrieved by code but keeps the spaces in the input field intact for improved UX. /// /// /// This converter is unconventional (inverted converter) in that the value is converted for the backend. /// The user wants to be able to input spaces while they're typing, but we don't want to save those spaces. /// public class TrimConverter : Converter { private readonly Lock inOutCacheLock = new(); /// /// Cache to remember the last known untrimmed value (here, the value) for trimmed values (here, the key). /// private readonly Dictionary inOutCache = new(); /// /// Converts trimmed value back to last known untrimmed value. /// public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is not string strValue) { return value; } lock (inOutCacheLock) { if (inOutCache.TryGetValue(strValue.Trim(), out string untrimmedValue)) { strValue = untrimmedValue; } } return strValue; } /// /// Converts untrimmed value back to trimmed value. /// public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value is not string strValue) { return value; } if (!strValue.StartsWith(' ') && !strValue.EndsWith(' ')) { // It's safe to reset cache now. lock (inOutCacheLock) { inOutCache.Clear(); } return strValue; } string trim = strValue.Trim(); lock (inOutCacheLock) { inOutCache[trim] = strValue; } return trim; } }