modified settings services
This commit is contained in:
@@ -4,7 +4,9 @@ using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using CursorLang.Interop;
|
||||
using CursorLang.Models;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace CursorLang.Services;
|
||||
|
||||
@@ -31,20 +33,36 @@ public sealed class SettingsService : IDisposable
|
||||
Converters = { new ColorJsonConverter(), new JsonStringEnumConverter() },
|
||||
};
|
||||
|
||||
private const string FileName = "settings.json";
|
||||
|
||||
private readonly string _filePath;
|
||||
private readonly string _inheritedFilePath;
|
||||
private readonly DispatcherTimer _saveTimer;
|
||||
private AppSettings? _settings;
|
||||
|
||||
public SettingsService()
|
||||
{
|
||||
string folder = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"CursorLang");
|
||||
_filePath = Path.Combine(folder, "settings.json");
|
||||
// Sliders change their values continuously, so writing to disk
|
||||
// is postponed until there is a pause in the changes
|
||||
private static readonly TimeSpan SaveDelay = TimeSpan.FromMilliseconds(500);
|
||||
|
||||
// Ползунки меняют значения непрерывно, поэтому запись на диск
|
||||
// откладывается до паузы в изменениях
|
||||
_saveTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) };
|
||||
public SettingsService()
|
||||
: this(
|
||||
Path.Combine(GetSettingsFolder(), FileName),
|
||||
Path.Combine(GetSeparateInstallFolder(), FileName),
|
||||
SaveDelay)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the storage locations and the save delay explicitly — thereby making it
|
||||
/// possible to check the work with the file without touching the settings of the
|
||||
/// user themselves.
|
||||
/// </summary>
|
||||
internal SettingsService(string filePath, string inheritedFilePath, TimeSpan saveDelay)
|
||||
{
|
||||
_filePath = filePath;
|
||||
_inheritedFilePath = inheritedFilePath;
|
||||
|
||||
_saveTimer = new DispatcherTimer { Interval = saveDelay };
|
||||
_saveTimer.Tick += OnSaveTimerTick;
|
||||
}
|
||||
|
||||
@@ -54,8 +72,29 @@ public sealed class SettingsService : IDisposable
|
||||
/// </summary>
|
||||
public AppSettings Load()
|
||||
{
|
||||
_settings = ReadFile() ?? CreateDefault();
|
||||
AppSettings? stored = ReadFile(_filePath);
|
||||
|
||||
// There is no file of our own — the application may well have been configured
|
||||
// before the move to a package. Taking the settings from there beats starting
|
||||
// from a blank slate
|
||||
bool inherited = stored is null && _filePath != _inheritedFilePath;
|
||||
if (inherited)
|
||||
{
|
||||
stored = ReadFile(_inheritedFilePath);
|
||||
inherited = stored is not null;
|
||||
}
|
||||
|
||||
_settings = stored ?? CreateDefault();
|
||||
_settings.PropertyChanged += OnSettingsChanged;
|
||||
|
||||
// Moved settings are fixed in the new place right away rather than on the
|
||||
// first edit: otherwise the application would read someone else's file every
|
||||
// time until then
|
||||
if (inherited)
|
||||
{
|
||||
Save();
|
||||
}
|
||||
|
||||
return _settings;
|
||||
}
|
||||
|
||||
@@ -89,16 +128,39 @@ public sealed class SettingsService : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private AppSettings? ReadFile()
|
||||
/// <summary>
|
||||
/// The folder the application writes its settings to.
|
||||
/// </summary>
|
||||
private static string GetSettingsFolder()
|
||||
{
|
||||
if (!PackageIdentityNative.IsPackaged)
|
||||
{
|
||||
return GetSeparateInstallFolder();
|
||||
}
|
||||
|
||||
// A package has a data folder of its own, which Windows creates and removes
|
||||
// itself. The application name is not appended to it: the folder belongs to it alone anyway
|
||||
return ApplicationData.Current.LocalFolder.Path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The settings folder of a separately installed application — the same source
|
||||
/// the package inherits the settings from on the first launch.
|
||||
/// </summary>
|
||||
private static string GetSeparateInstallFolder() => Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"CursorLang");
|
||||
|
||||
private static AppSettings? ReadFile(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(_filePath))
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return JsonSerializer.Deserialize<AppSettings>(File.ReadAllText(_filePath), SerializerOptions);
|
||||
return JsonSerializer.Deserialize<AppSettings>(File.ReadAllText(path), SerializerOptions);
|
||||
}
|
||||
catch (Exception e) when (e is IOException or UnauthorizedAccessException or JsonException)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user