using System.IO;
using System.Text.Json;
namespace TeamsISO.App.Services;
///
/// Persistent UI-side toggles that don't belong in
/// (which is the engine's domain model — framerate, NDI groups, ISO assignments).
///
/// Each toggle is a property on a single record persisted as JSON at
/// %LOCALAPPDATA%\TeamsISO\ui-prefs.json. Defaults match the original
/// in-memory behavior: HideLocalSelf=true (filter the operator's own preview
/// out of the participants list) and AutoDisableOnDeparture=false (a participant
/// going offline doesn't tear down their pipeline by default — operators
/// usually want to keep the routing in case they reconnect).
///
/// Centralizing these here means the settings VM doesn't have to plumb
/// individual Set methods to dedicated services for every new bool.
///
public static class UIPreferences
{
private static readonly object _gate = new();
private static string PrefsPath =>
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"TeamsISO", "ui-prefs.json");
///
/// Sort modes for the participants DataGrid. is the default
/// and matches the engine's discovery order (operators with custom Stream Deck
/// layouts sometimes prefer Alphabetical for stability across meetings).
///
public enum SortMode { JoinOrder, Alphabetical, OnlineFirst }
/// The on-disk shape. New fields added here become opt-in for older files via default values.
public sealed record Prefs(
bool HideLocalSelf = true,
bool AutoDisableOnDeparture = false,
SortMode ParticipantSort = SortMode.JoinOrder,
bool MinimizeToTray = false);
public static Prefs Load()
{
try
{
if (!File.Exists(PrefsPath)) return new Prefs();
var json = File.ReadAllText(PrefsPath);
return JsonSerializer.Deserialize(json) ?? new Prefs();
}
catch
{
return new Prefs();
}
}
public static void Save(Prefs prefs)
{
try
{
lock (_gate)
{
var dir = Path.GetDirectoryName(PrefsPath);
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
var json = JsonSerializer.Serialize(prefs, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(PrefsPath, json);
}
}
catch
{
// Disk full / permission denied — in-memory state still holds for this session.
}
}
}