using TeamsISO.Engine.Controller; using TeamsISO.Engine.Domain; namespace TeamsISO.App.ViewModels; /// /// Bindings for the global settings panel: framerate, resolution, aspect, audio, /// NDI groups (discovery + output), and the participant-list hide-Local toggle. /// public sealed class GlobalSettingsViewModel : ObservableObject { private readonly IIsoController _controller; private TargetFramerate _framerate; private TargetResolution _resolution; private AspectMode _aspect; private AudioMode _audio; private string _discoveryGroups; private string _outputGroups; private bool _hideLocalSelf = true; public GlobalSettingsViewModel(IIsoController controller) { _controller = controller; var current = controller.GlobalSettings; _framerate = current.Framerate; _resolution = current.Resolution; _aspect = current.Aspect; _audio = current.Audio; var groups = controller.GroupSettings; _discoveryGroups = groups.DiscoveryGroups ?? string.Empty; _outputGroups = groups.OutputGroups ?? string.Empty; ApplyCommand = new AsyncRelayCommand(ApplyAsync); } public IEnumerable AvailableFramerates => Enum.GetValues(); public IEnumerable AvailableResolutions => Enum.GetValues(); public IEnumerable AvailableAspectModes => Enum.GetValues(); public IEnumerable AvailableAudioModes => Enum.GetValues(); public TargetFramerate Framerate { get => _framerate; set => SetField(ref _framerate, value); } public TargetResolution Resolution { get => _resolution; set => SetField(ref _resolution, value); } public AspectMode Aspect { get => _aspect; set => SetField(ref _aspect, value); } public AudioMode Audio { get => _audio; set => SetField(ref _audio, value); } /// NDI discovery group(s) — comma-separated. Empty = default (Public). public string DiscoveryGroups { get => _discoveryGroups; set => SetField(ref _discoveryGroups, value); } /// NDI output group(s) — comma-separated. Empty = default (Public). public string OutputGroups { get => _outputGroups; set => SetField(ref _outputGroups, value); } /// /// Hide the user's own self-preview ("(Local)") from the participants list. /// On by default — operators rarely want to ISO-route their own preview. /// Read by when filtering the list it presents. /// public bool HideLocalSelf { get => _hideLocalSelf; set => SetField(ref _hideLocalSelf, value); } public AsyncRelayCommand ApplyCommand { get; } private async Task ApplyAsync() { var settings = new FrameProcessingSettings(_framerate, _resolution, _aspect, _audio); await _controller.SetGlobalSettingsAsync(settings, CancellationToken.None); var groups = new NdiGroupSettings( DiscoveryGroups: string.IsNullOrWhiteSpace(_discoveryGroups) ? null : _discoveryGroups.Trim(), OutputGroups: string.IsNullOrWhiteSpace(_outputGroups) ? null : _outputGroups.Trim()); await _controller.SetGroupSettingsAsync(groups, CancellationToken.None); } }