using System.ComponentModel; using System.Windows.Input; using CommunityToolkit.Mvvm.Input; using ClientApiPoC.OnPremiseApp.Services; using ClientApiPoC.Shared; using ClientApiPoC.Shared.Wpf; using ClientApiPoC.Shared.SignalR; namespace ClientApiPoC.OnPremiseApp { public class MainWindowViewModel : BaseViewModel { private ClientDataService _clientDataService; private TunnelClient _tunnelClient; #region Properties private string _apiServiceUrl = "http://localhost:5228/"; public string ApiServiceUrl { get => _apiServiceUrl; set { _apiServiceUrl = value; OnPropertyChanged(nameof(ApiServiceUrl)); } } private bool _tunnelClientIsConnecting = false; public bool TunnelClientIsConnecting { get => _tunnelClientIsConnecting; set { _tunnelClientIsConnecting = value; OnPropertyChanged(nameof(TunnelClientIsConnecting)); OnPropertyChanged(nameof(ConnectButtonEnabled)); OnPropertyChanged(nameof(UrlTextFieldEnabled)); } } public bool TunnelClientConnected => (_tunnelClient.IsConnected || _tunnelClient.IsConnecting); public string ConnectButtonText => (this.TunnelClientConnected ? "Disconnect" : "Connect"); public bool ConnectButtonEnabled => !this.TunnelClientIsConnecting; public bool UrlTextFieldEnabled => !this.TunnelClientIsConnecting && !this.TunnelClientConnected; private string _localClientData = ""; public string LocalClientData { get => _localClientData; set { _localClientData = value; OnPropertyChanged(nameof(LocalClientData)); OnPropertyChanged(nameof(SetLocalClientDataButtonEnabled)); } } public bool SetLocalClientDataButtonEnabled { get { if (string.IsNullOrEmpty(this.LocalClientData) && string.IsNullOrEmpty(_clientDataService.ClientData)) return false; return !string.Equals(this.LocalClientData, _clientDataService.ClientData); } } #endregion #region Commands public ICommand ToggleConnectionCommand { get; } public ICommand SetLocalClientDataCommand { get; } #endregion public MainWindowViewModel(ClientDataService clientDataService) { if (clientDataService == null) throw new ArgumentNullException(nameof(clientDataService)); _clientDataService = clientDataService; _tunnelClient = new TunnelClient(); _tunnelClient.PropertyChanged += TunnelClient_PropertyChanged; this.ToggleConnectionCommand = new AsyncRelayCommand(ToggleConnectionAsync); this.SetLocalClientDataCommand = new AsyncRelayCommand(SetLocalClientDataAsync); } private void TunnelClient_PropertyChanged(object? sender, PropertyChangedEventArgs e) { OnPropertyChanged(nameof(TunnelClientConnected)); OnPropertyChanged(nameof(ConnectButtonText)); OnPropertyChanged(nameof(UrlTextFieldEnabled)); } private async Task ToggleConnectionAsync() { if (this.TunnelClientIsConnecting) return; try { this.TunnelClientIsConnecting = true; if (this.TunnelClientConnected) { await _tunnelClient.DisconnectAsync(); } else { var url = this.ApiServiceUrl; if (string.IsNullOrWhiteSpace(url)) throw new Exception("Please provide a base url."); while (url.EndsWith('/')) url = url[..^1]; url += Routes.TUNNEL_PATH; await _tunnelClient.ConnectAsync(url, _clientDataService.ConfigureTunnelActions); } } catch (Exception ex) { await HandleErrorAsync(ex); } finally { this.TunnelClientIsConnecting = false; } } private async Task SetLocalClientDataAsync() { try { string? newClientData = this.LocalClientData; if (string.IsNullOrEmpty(newClientData)) newClientData = null; _clientDataService.ClientData = newClientData; } catch (Exception ex) { await HandleErrorAsync(ex); } finally { OnPropertyChanged(nameof(SetLocalClientDataButtonEnabled)); } } } }