LANCommander/LANCommander.Launcher.Avalonia/ViewModels/ServerSelectionViewModel.cs
Aaron Powell 8cf2139ccf feat: Add Avalonia launcher PoC with cross-platform UI
- Create LANCommander.Launcher.Avalonia project using Avalonia MVVM
- Implement server selection, login, and game library views
- Add library sidebar showing user's games
- Add depot/games list view with game details
- Integrate with LANCommander.Launcher.Services for:
  - DepotService, LibraryService, ImportService, MediaService
  - SDK authentication and connection clients
- Fix async initialization pattern to prevent UI thread deadlocks
- Add ConfigureAwait(false) to ServerConfigurationProvider.RefreshAsync
- Add Microsoft.Extensions.Http package for HttpClient DI

Key features:
- Server discovery and connection
- User authentication with credential persistence
- Library import from server to local SQLite cache
- Game icons and banners via MediaService
- Navigation between library, depot, and game details
2026-01-19 14:24:49 +11:00

86 lines
2.5 KiB
C#

using System;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LANCommander.SDK.Providers;
using LANCommander.SDK.Services;
namespace LANCommander.Launcher.Avalonia.ViewModels;
public partial class ServerSelectionViewModel : ViewModelBase
{
private readonly IConnectionClient _connectionClient;
private readonly SettingsProvider<Settings.Settings> _settingsProvider;
[ObservableProperty]
private string _serverAddress = string.Empty;
[ObservableProperty]
private string _statusMessage = string.Empty;
[ObservableProperty]
private bool _isLoading;
[ObservableProperty]
private bool _hasError;
public event EventHandler? ServerConnected;
public ServerSelectionViewModel(
IConnectionClient connectionClient,
SettingsProvider<Settings.Settings> settingsProvider)
{
_connectionClient = connectionClient;
_settingsProvider = settingsProvider;
// Load saved server address if available
if (_settingsProvider.CurrentValue.Authentication?.ServerAddress != null)
ServerAddress = _settingsProvider.CurrentValue.Authentication.ServerAddress.ToString();
}
[RelayCommand]
private async Task ConnectAsync()
{
if (string.IsNullOrWhiteSpace(ServerAddress))
{
StatusMessage = "Please enter a server address";
HasError = true;
return;
}
IsLoading = true;
HasError = false;
StatusMessage = "Testing connection...";
try
{
await _connectionClient.UpdateServerAddressAsync(ServerAddress);
var canConnect = await _connectionClient.PingAsync();
if (canConnect)
{
_settingsProvider.Update(s =>
{
s.Authentication.ServerAddress = new Uri(ServerAddress);
});
StatusMessage = "Connected!";
ServerConnected?.Invoke(this, EventArgs.Empty);
}
else
{
StatusMessage = "Could not connect to server. Please check the address and try again.";
HasError = true;
}
}
catch (Exception ex)
{
StatusMessage = $"Connection failed: {ex.Message}";
HasError = true;
}
finally
{
IsLoading = false;
}
}
}