Files
BookReader/BookReader/ViewModels/CalibreLibraryViewModel.cs
Курнат Андрей f0a3c19a3c qwen edit
2026-02-18 14:49:20 +03:00

187 lines
5.2 KiB
C#

using BookReader.Models;
using BookReader.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
namespace BookReader.ViewModels;
public partial class CalibreLibraryViewModel : BaseViewModel
{
private readonly ICalibreWebService _calibreWebService;
private readonly IBookParserService _bookParserService;
private readonly IDatabaseService _databaseService;
private readonly ISettingsService _settingsService;
private readonly INavigationService _navigationService;
private readonly ICachedImageLoadingService _imageLoadingService;
public ObservableCollection<CalibreBook> Books { get; } = new();
[ObservableProperty]
private string _searchQuery = string.Empty;
[ObservableProperty]
private bool _isConfigured;
[ObservableProperty]
private string _downloadStatus = string.Empty;
[ObservableProperty]
private bool _isRefreshing;
[ObservableProperty]
private string _connectionErrorMessage = string.Empty;
private int _currentPage;
public CalibreLibraryViewModel(
ICalibreWebService calibreWebService,
IBookParserService bookParserService,
IDatabaseService databaseService,
ISettingsService settingsService,
INavigationService navigationService,
ICachedImageLoadingService imageLoadingService)
{
_calibreWebService = calibreWebService;
_bookParserService = bookParserService;
_databaseService = databaseService;
_settingsService = settingsService;
_navigationService = navigationService;
_imageLoadingService = imageLoadingService;
Title = "Calibre Library";
}
[RelayCommand]
public async Task InitializeAsync()
{
var url = await _settingsService.GetAsync(SettingsKeys.CalibreUrl);
var username = await _settingsService.GetAsync(SettingsKeys.CalibreUsername);
var password = await _settingsService.GetSecurePasswordAsync();
IsConfigured = !string.IsNullOrWhiteSpace(url);
if (IsConfigured)
{
_calibreWebService.Configure(url, username, password);
await LoadBooksAsync();
}
}
[RelayCommand]
public async Task LoadBooksAsync()
{
if (IsBusy || !IsConfigured) return;
IsBusy = true;
_currentPage = 0;
ConnectionErrorMessage = string.Empty;
try
{
var books = await _calibreWebService.GetBooksAsync(SearchQuery, _currentPage);
Books.Clear();
foreach (var book in books)
{
Books.Add(book);
}
}
catch (Exception ex)
{
ConnectionErrorMessage = "No connection to Calibre server";
System.Diagnostics.Debug.WriteLine($"Error loading Calibre library: {ex.Message}");
}
finally
{
IsBusy = false;
}
}
[RelayCommand]
public async Task RefreshBooksAsync()
{
if (IsRefreshing || !IsConfigured) return;
IsRefreshing = true;
try
{
await LoadBooksAsync();
}
finally
{
IsRefreshing = false;
}
}
[RelayCommand]
public async Task LoadMoreBooksAsync()
{
if (IsBusy || !IsConfigured) return;
IsBusy = true;
_currentPage++;
try
{
var books = await _calibreWebService.GetBooksAsync(SearchQuery, _currentPage);
foreach (var book in books)
{
Books.Add(book);
}
}
catch { }
finally
{
IsBusy = false;
}
}
[RelayCommand]
public async Task SearchAsync()
{
await LoadBooksAsync();
}
[RelayCommand]
public async Task DownloadBookAsync(CalibreBook calibreBook)
{
if (calibreBook == null) return;
IsBusy = true;
DownloadStatus = $"Downloading {calibreBook.Title}...";
try
{
var progress = new Progress<double>(p =>
{
DownloadStatus = $"Downloading... {p * 100:F0}%";
});
var filePath = await _calibreWebService.DownloadBookAsync(calibreBook, progress);
var fileName = $"{calibreBook.Title}.{calibreBook.Format}";
var book = await _bookParserService.ParseAndStoreBookAsync(filePath, fileName);
book.CalibreId = calibreBook.Id;
if (calibreBook.CoverImage != null)
book.CoverImage = calibreBook.CoverImage;
await _databaseService.UpdateBookAsync(book);
DownloadStatus = "Download complete!";
await _navigationService.DisplayAlertAsync("Success", $"\"{calibreBook.Title}\" has been added to your library.", "OK");
}
catch (Exception ex)
{
await _navigationService.DisplayAlertAsync("Error", $"Failed to download: {ex.Message}", "OK");
}
finally
{
IsBusy = false;
DownloadStatus = string.Empty;
}
}
[RelayCommand]
public async Task OpenSettingsAsync()
{
await _navigationService.GoToAsync("settings");
}
}