@namespace MidrandBooks.Components @using Microsoft.AspNetCore.Components @using MidrandBooks.Models

My Secure Library

Access your licensed digital purchases. Sync progress instantly across all browsers.

@foreach (var format in Formats) { }
@if (FilteredLibraryItems().Any()) {
@foreach (var item in FilteredLibraryItems()) { var book = item.Book; var isEbook = item.Format == "ebook"; var isCached = OfflineBooks.Contains(book.Id); var isDownloading = DownloadingBookId == book.Id;
@if (!string.IsNullOrEmpty(book.CoverUrl)) { @book.Title } else {
@book.Category @book.Title By @book.Author
}
@item.Format @if (isEbook) { @if (isCached) { ✓ Cached } else { } }

@book.Title

By @book.Author
READING PROGRESS @(isEbook ? $"Page {item.CurrentPage + 1}" : "In Progress")
@if (isEbook) { } else { }
}
} else {

Your secure library is empty

Unlock local publishing titles, bestsellers, and studio audiobooks in our browse store. Purchases are instantly activated here.

}
@code { [Parameter] public List Purchases { get; set; } = new(); [Parameter] public List Books { get; set; } = new(); [Parameter] public List OfflineBooks { get; set; } = new(); [Parameter] public bool IsOfflineMode { get; set; } [Parameter] public EventCallback OnSelectBook { get; set; } [Parameter] public EventCallback OnReadBook { get; set; } [Parameter] public EventCallback OnPlayBook { get; set; } [Parameter] public EventCallback OnCacheBookOffline { get; set; } private string ActiveFormat { get; set; } = "all"; private string[] Formats = new string[] { "all", "ebook", "audiobook" }; private string? DownloadingBookId { get; set; } private void FilterByFormat(string format) { ActiveFormat = format; } private IEnumerable FilteredLibraryItems() { var items = new List(); foreach (var purchase in Purchases) { var matchedBook = Books.FirstOrDefault(b => b.Id == purchase.BookId); if (matchedBook != null) { items.Add(new LibraryItem { Book = matchedBook, Format = purchase.Format, CurrentPage = purchase.CurrentPage, Progress = purchase.Progress }); } } if (ActiveFormat == "all") return items; return items.Where(i => i.Format.Equals(ActiveFormat, StringComparison.OrdinalIgnoreCase)); } private async Task TriggerCacheBook(string bookId) { if (DownloadingBookId != null) return; DownloadingBookId = bookId; await Task.Delay(1500); // Simulate network latency await OnCacheBookOffline.InvokeAsync(bookId); DownloadingBookId = null; } private void HandleSelectBook(BookModel book) { OnSelectBook.InvokeAsync(book); } private void HandleReadBook(BookModel book) { OnReadBook.InvokeAsync(book); } private void HandlePlayBook(BookModel book) { OnPlayBook.InvokeAsync(book); } }