Files
ulapp/FieldLogger/ViewModels/SettingsViewModel.cs

135 lines
4.2 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FieldLogger.Models;
using FieldLogger.Services;
using FieldLogger.Services.Sync;
namespace FieldLogger.ViewModels;
public sealed partial class SettingsViewModel : ObservableObject
{
private readonly DeviceConnectionManager _manager;
private readonly SettingsService _settings;
private readonly IMqttSyncService _sync;
public DeviceConnectionManager Manager => _manager;
[ObservableProperty]
private string _mapsApiKey = "";
[ObservableProperty]
private bool _mqttEnabled;
[ObservableProperty]
private string _mqttHost = "";
[ObservableProperty]
private string _mqttPort = "8884";
[ObservableProperty]
private string _mqttOrgId = "";
[ObservableProperty]
private string _mqttPassword = "";
[ObservableProperty]
private string _syncStatus = "";
[ObservableProperty]
private bool _isSavingSync;
public string MqttClientId => _settings.MqttClientId;
public string AppVersion => AppInfo.Current.VersionString;
public SettingsViewModel(DeviceConnectionManager manager, SettingsService settings, IMqttSyncService sync)
{
_manager = manager;
_settings = settings;
_sync = sync;
MapsApiKey = settings.GoogleMapsApiKey;
MqttEnabled = settings.MqttEnabled;
MqttHost = settings.MqttHost;
MqttPort = settings.MqttPort.ToString();
MqttOrgId = settings.MqttOrgId;
SyncStatus = sync.Status;
_sync.StatusChanged += OnSyncStatusChanged;
}
partial void OnMapsApiKeyChanged(string value) => _settings.GoogleMapsApiKey = value.Trim();
[RelayCommand]
private async Task SaveSyncAsync()
{
if (!int.TryParse(MqttPort, out var port) || port is < 1 or > 65535)
{
await Shell.Current.DisplayAlert("Invalid MQTT Port", "Enter a port between 1 and 65535.", "OK");
return;
}
if (MqttEnabled && (string.IsNullOrWhiteSpace(MqttHost) || string.IsNullOrWhiteSpace(MqttOrgId)))
{
await Shell.Current.DisplayAlert("Incomplete Sync Settings", "Host and organization id are required.", "OK");
return;
}
IsSavingSync = true;
try
{
_settings.MqttHost = MqttHost;
_settings.MqttPort = port;
_settings.MqttOrgId = MqttOrgId;
_settings.MqttEnabled = MqttEnabled;
if (!string.IsNullOrWhiteSpace(MqttPassword))
{
await _settings.SetMqttPasswordAsync(MqttPassword);
MqttPassword = "";
}
if (MqttEnabled)
{
await _sync.ConnectAsync();
await Shell.Current.DisplayAlert("Sync Connected", "The durable MQTT queue is connected.", "OK");
}
else
{
await _sync.DisconnectAsync();
}
}
catch (Exception ex)
{
await Shell.Current.DisplayAlert("Sync Connection Failed", ex.Message, "OK");
}
finally
{
IsSavingSync = false;
}
}
private void OnSyncStatusChanged(object? sender, string status) =>
MainThread.BeginInvokeOnMainThread(() => SyncStatus = status);
[RelayCommand]
private Task ChangeLocatorAsync() => Shell.Current.GoToAsync($"devicescan?kind={DeviceKind.Locator}");
[RelayCommand]
private Task ChangeGpsAsync() => Shell.Current.GoToAsync($"devicescan?kind={DeviceKind.RtkGps}");
[RelayCommand]
private async Task ForgetLocatorAsync()
{
if (await ConfirmForgetAsync(_manager.LocatorName ?? "locating receiver"))
await _manager.ForgetDeviceAsync(DeviceKind.Locator);
}
[RelayCommand]
private async Task ForgetGpsAsync()
{
if (await ConfirmForgetAsync(_manager.GpsName ?? "RTK GPS receiver"))
await _manager.ForgetDeviceAsync(DeviceKind.RtkGps);
}
private static Task<bool> ConfirmForgetAsync(string name) =>
Shell.Current.DisplayAlert("Forget Device",
$"Forget \"{name}\"? The app will no longer auto-connect to it.", "Forget", "Cancel");
}