using System.Collections.ObjectModel; using System.Windows.Input; using ytLive.Helpers; using ytLive.Services; namespace ytLive.ViewModels; public class CameraPickerCandidate { public CameraDeviceInfo Device { get; } public string Name => Device.DisplayName; public CameraPickerCandidate(CameraDeviceInfo device) { Device = device; } } public class CameraPickerViewModel : ViewModelBase { private readonly ICameraEnumerator _enumerator; private CameraPickerCandidate? _selectedCamera; private bool _isLoading = true; public ObservableCollection Cameras { get; } = new(); public bool IsLoading { get => _isLoading; private set => SetProperty(ref _isLoading, value); } public bool HasCameras => !IsLoading && Cameras.Count > 0; public bool NoCameras => !IsLoading && Cameras.Count == 0; public CameraPickerCandidate? SelectedCamera { get => _selectedCamera; set { if (SetProperty(ref _selectedCamera, value)) CommandManager.InvalidateRequerySuggested(); } } public ICommand UseSelectedCommand { get; } public ICommand CancelCommand { get; } public event Action? UseRequested; public event Action? CancelRequested; public CameraPickerViewModel(ICameraEnumerator enumerator) { _enumerator = enumerator; UseSelectedCommand = new RelayCommand( _ => { if (SelectedCamera != null) UseRequested?.Invoke(SelectedCamera.Device); }, _ => SelectedCamera != null); CancelCommand = new RelayCommand(_ => CancelRequested?.Invoke()); _ = LoadAsync(); } private async Task LoadAsync() { IsLoading = true; try { var devices = await _enumerator.GetCamerasAsync(); Cameras.Clear(); foreach (var device in devices) Cameras.Add(new CameraPickerCandidate(device)); if (Cameras.Count > 0) SelectedCamera = Cameras[0]; } catch (Exception ex) { AppLog.Write($"CameraPickerViewModel: enumerating cameras failed: {ex.Message}"); } finally { IsLoading = false; OnPropertyChanged(nameof(HasCameras)); OnPropertyChanged(nameof(NoCameras)); CommandManager.InvalidateRequerySuggested(); } } }