157 lines
4.3 KiB
C#
157 lines
4.3 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;
|
|
|
|
public ObservableCollection<CalibreBook> Books { get; } = new();
|
|
|
|
[ObservableProperty]
|
|
private string _searchQuery = string.Empty;
|
|
|
|
[ObservableProperty]
|
|
private bool _isConfigured;
|
|
|
|
[ObservableProperty]
|
|
private string _downloadStatus = string.Empty;
|
|
|
|
private int _currentPage;
|
|
|
|
public CalibreLibraryViewModel(
|
|
ICalibreWebService calibreWebService,
|
|
IBookParserService bookParserService,
|
|
IDatabaseService databaseService,
|
|
ISettingsService settingsService)
|
|
{
|
|
_calibreWebService = calibreWebService;
|
|
_bookParserService = bookParserService;
|
|
_databaseService = databaseService;
|
|
_settingsService = settingsService;
|
|
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.GetAsync(SettingsKeys.CalibrePassword);
|
|
|
|
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;
|
|
|
|
try
|
|
{
|
|
var books = await _calibreWebService.GetBooksAsync(SearchQuery, _currentPage);
|
|
Books.Clear();
|
|
foreach (var book in books)
|
|
{
|
|
Books.Add(book);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await Shell.Current.DisplayAlert("Error", $"Failed to load library: {ex.Message}", "OK");
|
|
}
|
|
finally
|
|
{
|
|
IsBusy = 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 Shell.Current.DisplayAlert("Success", $"\"{calibreBook.Title}\" has been added to your library.", "OK");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await Shell.Current.DisplayAlert("Error", $"Failed to download: {ex.Message}", "OK");
|
|
}
|
|
finally
|
|
{
|
|
IsBusy = false;
|
|
DownloadStatus = string.Empty;
|
|
}
|
|
}
|
|
|
|
[RelayCommand]
|
|
public async Task OpenSettingsAsync()
|
|
{
|
|
await Shell.Current.GoToAsync("settings");
|
|
}
|
|
} |