Skip to content

Commit

Permalink
Persist settings in each tools (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
veler authored Oct 10, 2021
1 parent 6d3e3b1 commit 7020ca0
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 52 deletions.
7 changes: 7 additions & 0 deletions src/dev/impl/DevToys/Api/Core/Settings/SettingDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ namespace DevToys.Api.Core.Settings
/// <param name="defaultValue">The default value of the setting.</param>
public SettingDefinition(string name, bool isRoaming, T defaultValue)
{
if (string.IsNullOrEmpty(name) || name.Length > 255)
{
// For both LocalSettings and RoamingSettings, the name of each setting can be 255 characters in length at most.
// see https://docs.microsoft.com/en-us/uwp/api/windows.storage.applicationdata.localsettings?view=winrt-22000#remarks
throw new ArgumentOutOfRangeException(nameof(name));
}

IsRoaming = isRoaming;
Name = name;
DefaultValue = defaultValue;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable

using DevToys.Api.Core.Settings;
using DevToys.Api.Tools;
using DevToys.Core;
using DevToys.Core.Threading;
Expand All @@ -16,17 +17,35 @@ namespace DevToys.ViewModels.Tools.Base64EncoderDecoder
[Export(typeof(Base64EncoderDecoderToolViewModel))]
public class Base64EncoderDecoderToolViewModel : ObservableRecipient, IToolViewModel
{
/// <summary>
/// Whether the tool should encode or decode Base64.
/// </summary>
private static readonly SettingDefinition<string> Conversion
= new(
name: $"{nameof(Base64EncoderDecoderToolViewModel)}.{nameof(Conversion)}",
isRoaming: true,
defaultValue: DefaultConversion);

/// <summary>
/// Whether the tool should encode/decode in Unicode or ASCII.
/// </summary>
private static readonly SettingDefinition<string> Encoder
= new(
name: $"{nameof(Base64EncoderDecoderToolViewModel)}.{nameof(Encoder)}",
isRoaming: true,
defaultValue: DefaultEncoding);

private const string DefaultEncoding = "UTF-8";
private const string DefaultConversion = "Encode";
internal const string DecodeConversion = "Decode";

private readonly ISettingsProvider _settingsProvider;
private readonly Queue<string> _conversionQueue = new();

private string? _inputValue;
private string? _outputValue;
private string _encodingMode = DefaultEncoding;
private string _conversionMode = DefaultConversion;
private bool _conversionInProgress;
private bool _setPropertyInProgress;
private readonly Queue<string> _conversionQueue = new();

public Type View { get; } = typeof(Base64EncoderDecoderToolPage);

Expand Down Expand Up @@ -60,14 +79,18 @@ internal string? OutputValue
/// </summary>
internal string ConversionMode
{
get => _conversionMode;
get => _settingsProvider.GetSetting(Conversion);
set
{
if (!_setPropertyInProgress)
{
_setPropertyInProgress = true;
ThreadHelper.ThrowIfNotOnUIThread();
SetProperty(ref _conversionMode, value);
if (!string.Equals(_settingsProvider.GetSetting(Conversion), value, StringComparison.Ordinal))
{
_settingsProvider.SetSetting(Conversion, value);
OnPropertyChanged();
}
InputValue = OutputValue;
_setPropertyInProgress = false;
}
Expand All @@ -79,15 +102,25 @@ internal string ConversionMode
/// </summary>
internal string EncodingMode
{
get => _encodingMode;
get => _settingsProvider.GetSetting(Encoder);
set
{
ThreadHelper.ThrowIfNotOnUIThread();
SetProperty(ref _encodingMode, value);
QueueConversionCalculation();
if (!string.Equals(_settingsProvider.GetSetting(Encoder), value, StringComparison.Ordinal))
{
_settingsProvider.SetSetting(Encoder, value);
OnPropertyChanged();
QueueConversionCalculation();
}
}
}

[ImportingConstructor]
public Base64EncoderDecoderToolViewModel(ISettingsProvider settingsProvider)
{
_settingsProvider = settingsProvider;
}

private void QueueConversionCalculation()
{
_conversionQueue.Enqueue(InputValue ?? string.Empty);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable

using DevToys.Api.Core.Settings;
using DevToys.Api.Tools;
using DevToys.Core;
using DevToys.Core.Threading;
Expand All @@ -18,10 +19,19 @@ namespace DevToys.ViewModels.Tools.HashGenerator
[Export(typeof(HashGeneratorToolViewModel))]
public sealed class HashGeneratorToolViewModel : ObservableRecipient, IToolViewModel
{
/// <summary>
/// Whether the generated hash should be uppercase or lowercase.
/// </summary>
private static readonly SettingDefinition<bool> Uppercase
= new(
name: $"{nameof(HashGeneratorToolViewModel)}.{nameof(Uppercase)}",
isRoaming: true,
defaultValue: false);

private readonly ISettingsProvider _settingsProvider;
private readonly Queue<string> _hashCalculationQueue = new();

private bool _calculationInProgress;
private bool _isUppercase;
private string? _input;
private string? _md5;
private string? _sha1;
Expand All @@ -34,11 +44,15 @@ public sealed class HashGeneratorToolViewModel : ObservableRecipient, IToolViewM

internal bool IsUppercase
{
get => _isUppercase;
get => _settingsProvider.GetSetting(Uppercase);
set
{
SetProperty(ref _isUppercase, value);
QueueHashCalculation();
if (_settingsProvider.GetSetting(Uppercase) != value)
{
_settingsProvider.SetSetting(Uppercase, value);
OnPropertyChanged();
QueueHashCalculation();
}
}
}

Expand Down Expand Up @@ -76,6 +90,12 @@ internal string? SHA512
private set => SetProperty(ref _sha512, value);
}

[ImportingConstructor]
public HashGeneratorToolViewModel(ISettingsProvider settingsProvider)
{
_settingsProvider = settingsProvider;
}

private void QueueHashCalculation()
{
_hashCalculationQueue.Enqueue(Input ?? string.Empty);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ namespace DevToys.ViewModels.Tools.JsonFormatter
[Export(typeof(JsonFormatterToolViewModel))]
public sealed class JsonFormatterToolViewModel : ObservableRecipient, IToolViewModel
{
/// <summary>
/// The indentation to apply while formatting.
/// </summary>
private static readonly SettingDefinition<string> Indentation
= new(
name: $"{nameof(JsonFormatterToolViewModel)}.{nameof(Indentation)}",
isRoaming: true,
defaultValue: TwoSpaceIndentation);

private const string TwoSpaceIndentation = "TwoSpaces";
private const string FourSpaceIndentation = "FourSpaces";
private const string OneTabIndentation = "OneTab";
Expand All @@ -30,7 +39,6 @@ public sealed class JsonFormatterToolViewModel : ObservableRecipient, IToolViewM
private bool _formattingInProgress;
private string? _inputValue;
private string? _outputValue;
private string _indentation = TwoSpaceIndentation;

public Type View { get; } = typeof(JsonFormatterToolPage);

Expand All @@ -39,13 +47,17 @@ public sealed class JsonFormatterToolViewModel : ObservableRecipient, IToolViewM
/// <summary>
/// Gets or sets the desired indentation.
/// </summary>
internal string Indentation
internal string IndentationMode
{
get => _indentation;
get => SettingsProvider.GetSetting(Indentation);
set
{
SetProperty(ref _indentation, value);
QueueFormatting();
if (!string.Equals(SettingsProvider.GetSetting(Indentation), value, StringComparison.Ordinal))
{
SettingsProvider.SetSetting(Indentation, value);
OnPropertyChanged();
QueueFormatting();
}
}
}

Expand Down Expand Up @@ -124,7 +136,7 @@ private bool FormatJson(string input, out string output)
using (var stringWriter = new StringWriter(stringBuilder))
using (var jsonTextWriter = new JsonTextWriter(stringWriter))
{
switch (Indentation)
switch (IndentationMode)
{
case TwoSpaceIndentation:
jsonTextWriter.Formatting = Formatting.Indented;
Expand Down Expand Up @@ -169,7 +181,7 @@ private bool FormatJson(string input, out string output)
}
catch (Exception ex) //some other exception
{
Logger.LogFault("Json formatter", ex, $"Indentation: {Indentation}");
Logger.LogFault("Json formatter", ex, $"Indentation: {IndentationMode}");
output = ex.Message;
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ namespace DevToys.ViewModels.Tools.JsonYaml
[Export(typeof(JsonYamlToolViewModel))]
public sealed class JsonYamlToolViewModel : ObservableRecipient, IToolViewModel
{
/// <summary>
/// Whether the tool should convert JSON to YAML or YAML to JSON.
/// </summary>
private static readonly SettingDefinition<string> Conversion
= new(
name: $"{nameof(JsonYamlToolViewModel)}.{nameof(Conversion)}",
isRoaming: true,
defaultValue: JsonToYaml);

/// <summary>
/// The indentation to apply while converting.
/// </summary>
private static readonly SettingDefinition<string> Indentation
= new(
name: $"{nameof(JsonYamlToolViewModel)}.{nameof(Indentation)}",
isRoaming: true,
defaultValue: TwoSpaceIndentation);

internal const string JsonToYaml = nameof(JsonToYaml);
internal const string YamlToJson = nameof(YamlToJson);
private const string TwoSpaceIndentation = "TwoSpaces";
Expand All @@ -36,8 +54,6 @@ public sealed class JsonYamlToolViewModel : ObservableRecipient, IToolViewModel
private string? _inputValueLanguage;
private string? _outputValue;
private string? _outputValueLanguage;
private string _indentation = TwoSpaceIndentation;
private string _conversionMode = JsonToYaml;

public Type View { get; } = typeof(JsonYamlToolPage);

Expand All @@ -48,34 +64,38 @@ public sealed class JsonYamlToolViewModel : ObservableRecipient, IToolViewModel
/// </summary>
internal string ConversionMode
{
get => _conversionMode;
get => SettingsProvider.GetSetting(Conversion);
set
{
if (!_setPropertyInProgress)
{
_setPropertyInProgress = true;
ThreadHelper.ThrowIfNotOnUIThread();
SetProperty(ref _conversionMode, value);

if (string.Equals(value, JsonToYaml))
if (!string.Equals(SettingsProvider.GetSetting(Conversion), value, StringComparison.Ordinal))
{
if (JsonHelper.IsValidJson(OutputValue))
{
InputValue = OutputValue;
}
SettingsProvider.SetSetting(Conversion, value);
OnPropertyChanged();

InputValueLanguage = "json";
OutputValueLanguage = "yaml";
}
else
{
if (YamlHelper.IsValidYaml(OutputValue))
if (string.Equals(value, JsonToYaml))
{
InputValue = OutputValue;
if (JsonHelper.IsValidJson(OutputValue))
{
InputValue = OutputValue;
}

InputValueLanguage = "json";
OutputValueLanguage = "yaml";
}
else
{
if (YamlHelper.IsValidYaml(OutputValue))
{
InputValue = OutputValue;
}

InputValueLanguage = "yaml";
OutputValueLanguage = "json";
InputValueLanguage = "yaml";
OutputValueLanguage = "json";
}
}

_setPropertyInProgress = false;
Expand All @@ -86,13 +106,17 @@ internal string ConversionMode
/// <summary>
/// Gets or sets the desired indentation.
/// </summary>
internal string Indentation
internal string IndentationMode
{
get => _indentation;
get => SettingsProvider.GetSetting(Indentation);
set
{
SetProperty(ref _indentation, value);
QueueConversion();
if (!string.Equals(SettingsProvider.GetSetting(Indentation), value, StringComparison.Ordinal))
{
SettingsProvider.SetSetting(Indentation, value);
OnPropertyChanged();
QueueConversion();
}
}
}

Expand Down Expand Up @@ -199,7 +223,7 @@ private bool ConvertJsonToYaml(string input, out string output)
if (jsonObject is not null && jsonObject is not string)
{
int indent = 0;
switch (Indentation)
switch (IndentationMode)
{
case TwoSpaceIndentation:
indent = 2;
Expand Down Expand Up @@ -263,7 +287,7 @@ private bool ConvertYamlToJson(string input, out string output)
using (var stringWriter = new StringWriter(stringBuilder))
using (var jsonTextWriter = new JsonTextWriter(stringWriter))
{
switch (Indentation)
switch (IndentationMode)
{
case TwoSpaceIndentation:
jsonTextWriter.Formatting = Formatting.Indented;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ namespace DevToys.ViewModels.Tools.TextDiff
[Export(typeof(TextDiffToolViewModel))]
public sealed class TextDiffToolViewModel : ObservableRecipient, IToolViewModel
{
private bool _inlineMode;
/// <summary>
/// Whether the text difference should be displayed inlined or side by side.
/// </summary>
private static readonly SettingDefinition<bool> Inline
= new(
name: $"{nameof(TextDiffToolViewModel)}.{nameof(Inline)}",
isRoaming: true,
defaultValue: false);

private string? _oldText;
private string? _newText;

Expand All @@ -24,8 +32,15 @@ public sealed class TextDiffToolViewModel : ObservableRecipient, IToolViewModel

internal bool InlineMode
{
get => _inlineMode;
set => SetProperty(ref _inlineMode, value, broadcast: true);
get => SettingsProvider.GetSetting(Inline);
set
{
if (SettingsProvider.GetSetting(Inline) != value)
{
SettingsProvider.SetSetting(Inline, value);
OnPropertyChanged();
}
}
}

internal string? OldText
Expand Down
Loading

0 comments on commit 7020ca0

Please sign in to comment.