feat(diff): persist diff view mode and wrap preference in ui config
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using ClaudeDo.Data;
|
||||
|
||||
namespace ClaudeDo.Ui;
|
||||
@@ -10,24 +11,40 @@ public sealed class AppSettings
|
||||
public string Language { get; set; } = "";
|
||||
public string AccentPreset { get; set; } = "";
|
||||
|
||||
private static readonly string ConfigPath = Paths.Expand("~/.todo-app/ui.config.json");
|
||||
/// Diff viewer layout: "unified" or "split". A view preference, so it lives here in
|
||||
/// ui.config.json rather than in the worker-owned AppSettingsEntity.
|
||||
public string DiffViewMode { get; set; } = "unified";
|
||||
public bool DiffWrapLines { get; set; }
|
||||
|
||||
public static AppSettings Load()
|
||||
private static readonly string DefaultConfigPath = Paths.Expand("~/.todo-app/ui.config.json");
|
||||
|
||||
/// Where this instance persists. Instance-level (not static) so tests can redirect it —
|
||||
/// the diff-viewer toggles call Save() on every flip.
|
||||
[JsonIgnore]
|
||||
public string ConfigPath { get; set; } = DefaultConfigPath;
|
||||
|
||||
public static AppSettings Load(string? configPath = null)
|
||||
{
|
||||
var path = configPath ?? DefaultConfigPath;
|
||||
try
|
||||
{
|
||||
if (File.Exists(ConfigPath))
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var json = File.ReadAllText(ConfigPath);
|
||||
return JsonSerializer.Deserialize<AppSettings>(json,
|
||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new();
|
||||
var json = File.ReadAllText(path);
|
||||
var loaded = JsonSerializer.Deserialize<AppSettings>(json,
|
||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||
if (loaded is not null)
|
||||
{
|
||||
loaded.ConfigPath = path;
|
||||
return loaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Fall through to defaults
|
||||
}
|
||||
return new();
|
||||
return new AppSettings { ConfigPath = path };
|
||||
}
|
||||
|
||||
public void Save()
|
||||
|
||||
@@ -1,22 +1,68 @@
|
||||
using System.Text.Json;
|
||||
using ClaudeDo.Ui;
|
||||
using Xunit;
|
||||
|
||||
namespace ClaudeDo.Ui.Tests;
|
||||
|
||||
public class AppSettingsTests
|
||||
{
|
||||
private static string TempConfigPath() =>
|
||||
Path.Combine(Path.GetTempPath(), $"claudedo-uicfg-{Guid.NewGuid():N}.json");
|
||||
|
||||
[Fact]
|
||||
public void Language_defaults_to_empty()
|
||||
public void DiffPreferences_DefaultToUnifiedAndNoWrap()
|
||||
{
|
||||
Assert.Equal("", new AppSettings().Language);
|
||||
var settings = new AppSettings();
|
||||
|
||||
Assert.Equal("unified", settings.DiffViewMode);
|
||||
Assert.False(settings.DiffWrapLines);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Language_round_trips_through_json()
|
||||
public void DiffPreferences_SurviveSaveAndLoad()
|
||||
{
|
||||
var json = JsonSerializer.Serialize(new AppSettings { Language = "de" });
|
||||
var back = JsonSerializer.Deserialize<AppSettings>(json,
|
||||
var path = TempConfigPath();
|
||||
try
|
||||
{
|
||||
new AppSettings { ConfigPath = path, DiffViewMode = "split", DiffWrapLines = true }.Save();
|
||||
|
||||
var restored = AppSettings.Load(path);
|
||||
|
||||
Assert.Equal("split", restored.DiffViewMode);
|
||||
Assert.True(restored.DiffWrapLines);
|
||||
Assert.Equal(path, restored.ConfigPath);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(path)) File.Delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigPath_IsNotWrittenIntoTheConfigFile()
|
||||
{
|
||||
var path = TempConfigPath();
|
||||
try
|
||||
{
|
||||
new AppSettings { ConfigPath = path }.Save();
|
||||
|
||||
Assert.DoesNotContain("ConfigPath", File.ReadAllText(path), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (File.Exists(path)) File.Delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DiffPreferences_ReadFromCamelCasedConfig()
|
||||
{
|
||||
const string json = """{"diffViewMode":"split","diffWrapLines":true}""";
|
||||
|
||||
var restored = JsonSerializer.Deserialize<AppSettings>(json,
|
||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!;
|
||||
Assert.Equal("de", back.Language);
|
||||
|
||||
Assert.Equal("split", restored.DiffViewMode);
|
||||
Assert.True(restored.DiffWrapLines);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user