LANCommander/LANCommander.Launcher.Avalonia/ViewModels/ShellViewModel.cs

163 lines
5.3 KiB
C#

using System;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LANCommander.Launcher.Avalonia.ViewModels.Components;
using LANCommander.Launcher.Data.Models;
using LANCommander.Launcher.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace LANCommander.Launcher.Avalonia.ViewModels;
public partial class ShellViewModel : ViewModelBase
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<ShellViewModel> _logger;
[ObservableProperty]
private ViewModelBase? _contentView;
[ObservableProperty]
private bool _isLoading;
// Child view models
public LibrarySidebarViewModel Sidebar { get; private set; } = null!;
public GamesListViewModel GamesListViewModel { get; private set; } = null!;
public GameDetailViewModel GameDetailViewModel { get; private set; } = null!;
public event EventHandler? LogoutRequested;
public ShellViewModel(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_logger = serviceProvider.GetRequiredService<ILogger<ShellViewModel>>();
}
public async Task InitializeAsync()
{
_logger.LogInformation("ShellViewModel initializing...");
// Create child view models
Sidebar = new LibrarySidebarViewModel(_serviceProvider);
GamesListViewModel = new GamesListViewModel(_serviceProvider);
GameDetailViewModel = new GameDetailViewModel(_serviceProvider);
// Wire up events
Sidebar.DepotSelected += OnDepotSelected;
Sidebar.ItemSelected += OnLibraryItemSelected;
Sidebar.RefreshRequested += async (_, _) => await RefreshAsync();
Sidebar.LogoutRequested += async (_, _) => await LogoutAsync();
GamesListViewModel.GameSelected += OnGameSelected;
GameDetailViewModel.BackRequested += OnBackFromGameDetail;
GameDetailViewModel.LibraryChanged += OnLibraryChanged;
// Import library from server and load data
await ImportAndLoadAsync();
// Default to showing depot
ShowDepot();
_logger.LogInformation("ShellViewModel initialization complete");
}
private async Task ImportAndLoadAsync()
{
IsLoading = true;
Sidebar.StatusMessage = "Importing library...";
_logger.LogInformation("Starting library import...");
try
{
using var scope = _serviceProvider.CreateScope();
var importService = scope.ServiceProvider.GetRequiredService<ImportService>();
await importService.ImportLibraryAsync();
_logger.LogInformation("Library import complete");
// Load sidebar and games list
await Sidebar.LoadAsync();
await GamesListViewModel.LoadGamesAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Import failed");
Sidebar.StatusMessage = $"Import failed: {ex.Message}";
}
finally
{
IsLoading = false;
}
}
[RelayCommand]
private async Task RefreshAsync()
{
await ImportAndLoadAsync();
}
[RelayCommand]
private async Task LogoutAsync()
{
using var scope = _serviceProvider.CreateScope();
var authService = scope.ServiceProvider.GetRequiredService<AuthenticationService>();
await authService.Logout();
LogoutRequested?.Invoke(this, EventArgs.Empty);
}
private void ShowDepot()
{
Sidebar.SelectDepot();
ContentView = GamesListViewModel;
_logger.LogDebug("Showing depot view");
}
private void OnDepotSelected(object? sender, EventArgs e)
{
ContentView = GamesListViewModel;
}
private async void OnLibraryItemSelected(object? sender, LibraryItemViewModel item)
{
using var scope = _serviceProvider.CreateScope();
var libraryService = scope.ServiceProvider.GetRequiredService<LibraryService>();
var listItem = await libraryService.GetItemAsync(item.Id);
if (listItem?.DataItem is Game game)
{
GameDetailViewModel.LoadGame(game);
ContentView = GameDetailViewModel;
}
}
private async void OnGameSelected(object? sender, SDK.Models.Game game)
{
// Update sidebar selection if game is in library
Sidebar.SelectItemById(game.Id);
if (Sidebar.SelectedItem == null)
{
Sidebar.ClearSelection();
}
ContentView = GameDetailViewModel;
await GameDetailViewModel.LoadGameAsync(game);
}
private void OnBackFromGameDetail(object? sender, EventArgs e)
{
ShowDepot();
}
private async void OnLibraryChanged(object? sender, EventArgs e)
{
_logger.LogInformation("Library changed, refreshing sidebar and games list...");
// Refresh the sidebar to show updated library
await Sidebar.LoadAsync();
// Refresh the games list to update "In Library" status
await GamesListViewModel.LoadGamesAsync();
}
}